@dguido/google-workspace-mcp 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +40 -14
- package/dist/index.js +308 -274
- package/dist/index.js.map +4 -4
- package/package.json +3 -2
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/utils/logging.ts", "../src/utils/responses.ts", "../src/utils/validation.ts", "../src/utils/services.ts", "../src/utils/timeout.ts", "../src/utils/retry.ts", "../src/utils/elicitation.ts", "../src/utils/progress.ts", "../src/utils/pathCache.ts", "../src/utils/mime.ts", "../src/utils/index.ts", "../src/index.ts", "../src/auth/client.ts", "../src/auth/utils.ts", "../src/auth/server.ts", "../src/auth/tokenManager.ts", "../src/auth.ts", "../src/config/
|
|
4
|
-
"sourcesContent": ["/**\n * Logging utility for the Google Drive MCP server.\n * Outputs timestamped messages to stderr to avoid interfering with MCP communication.\n */\nexport function log(message: string, data?: unknown): void {\n const timestamp = new Date().toISOString();\n const logMessage = data\n ? `[${timestamp}] ${message}: ${JSON.stringify(data)}`\n : `[${timestamp}] ${message}`;\n console.error(logMessage);\n}\n", "import { log } from \"./logging.js\";\n\n/**\n * Maximum character limit for response content.\n * Large responses can overwhelm agent context windows.\n */\nconst CHARACTER_LIMIT = 25000;\n\nexport interface TruncationResult {\n content: string;\n truncated: boolean;\n originalLength: number;\n}\n\n/**\n * Truncate response content if it exceeds the character limit.\n * Helps prevent overwhelming agent context windows with large API responses.\n */\nexport function truncateResponse(content: string): TruncationResult {\n if (content.length <= CHARACTER_LIMIT) {\n return { content, truncated: false, originalLength: content.length };\n }\n return {\n content:\n content.slice(0, CHARACTER_LIMIT) +\n `\\n\\n[TRUNCATED: Response exceeded ${CHARACTER_LIMIT} characters. ` +\n `Original length: ${content.length}. Consider using more specific queries.]`,\n truncated: true,\n originalLength: content.length,\n };\n}\n\nexport interface ToolResponse {\n content: Array<{ type: string; text: string }>;\n isError: boolean;\n structuredContent?: Record<string, unknown>;\n [x: string]: unknown; // Allow additional properties for MCP SDK compatibility\n}\n\n/**\n * Standard error codes for categorizing errors.\n * Clients can use these to handle specific error types programmatically.\n * Aligned with MCP spec JSON-RPC error codes where applicable.\n */\nexport type ErrorCode =\n | \"NOT_FOUND\" // -30003\n | \"ALREADY_EXISTS\"\n | \"PERMISSION_DENIED\"\n | \"INVALID_INPUT\" // -32602\n | \"RATE_LIMITED\"\n | \"QUOTA_EXCEEDED\" // -30002\n | \"AUTH_REQUIRED\" // -31001\n | \"INVALID_TOKEN\" // -31002\n | \"RESOURCE_LOCKED\" // -30001\n | \"UNSUPPORTED_OPERATION\"\n | \"INTERNAL_ERROR\";\n\nexport interface ErrorOptions {\n /** Standard error code for programmatic handling */\n code?: ErrorCode;\n /** Additional context about the error */\n context?: Record<string, unknown>;\n}\n\n/**\n * Create a success response for a tool call.\n */\nexport function successResponse(text: string): ToolResponse {\n return { content: [{ type: \"text\", text }], isError: false };\n}\n\n/**\n * Create a structured response for a tool call.\n * Includes both human-readable text and machine-parseable structured data.\n * Use this for tools that return structured data (metadata, lists, quotas, etc.).\n */\nexport function structuredResponse(text: string, data: Record<string, unknown>): ToolResponse {\n return {\n content: [{ type: \"text\", text }],\n structuredContent: data,\n isError: false,\n };\n}\n\n/**\n * Create an error response for a tool call.\n * Logs the error message before returning.\n *\n * @param message - Human-readable error message\n * @param options - Optional error code and context for programmatic handling\n */\nexport function errorResponse(message: string, options?: ErrorOptions): ToolResponse {\n log(\"Error\", { message, ...options });\n\n const response: ToolResponse = {\n content: [{ type: \"text\", text: `Error: ${message}` }],\n isError: true,\n };\n\n if (options?.code || options?.context) {\n response.structuredContent = {\n ...(options.code && { errorCode: options.code }),\n ...(options.context && { context: options.context }),\n };\n }\n\n return response;\n}\n", "import type { z } from \"zod\";\nimport { errorResponse } from \"./responses.js\";\nimport type { ToolResponse } from \"./responses.js\";\n\n/**\n * Result type for validation helper.\n * Either returns validated data or an error response.\n */\nexport type ValidationResult<T> =\n | { success: true; data: T }\n | { success: false; response: ToolResponse };\n\n/**\n * Validates arguments against a Zod schema.\n * Returns a discriminated union to allow clean early returns.\n *\n * @example\n * const validation = validateArgs(MySchema, args);\n * if (!validation.success) return validation.response;\n * const data = validation.data;\n */\nexport function validateArgs<T>(schema: z.ZodSchema<T>, args: unknown): ValidationResult<T> {\n const result = schema.safeParse(args);\n if (!result.success) {\n return {\n success: false,\n response: errorResponse(result.error.issues[0].message),\n };\n }\n return { success: true, data: result.data };\n}\n", "import { google, docs_v1, sheets_v4, slides_v1, calendar_v3, gmail_v1 } from \"googleapis\";\nimport type { OAuth2Client } from \"google-auth-library\";\n\n// Cached service instances\nlet docsService: docs_v1.Docs | null = null;\nlet sheetsService: sheets_v4.Sheets | null = null;\nlet slidesService: slides_v1.Slides | null = null;\nlet calendarService: calendar_v3.Calendar | null = null;\nlet gmailService: gmail_v1.Gmail | null = null;\nlet lastAuthClient: OAuth2Client | null = null;\n\n/**\n * Clear cached services. Should be called when auth changes.\n */\nexport function clearServiceCache(): void {\n docsService = null;\n sheetsService = null;\n slidesService = null;\n calendarService = null;\n gmailService = null;\n lastAuthClient = null;\n}\n\n/**\n * Check if auth client has changed and clear cache if needed.\n */\nfunction checkAuthClient(authClient: OAuth2Client): void {\n if (lastAuthClient !== authClient) {\n clearServiceCache();\n lastAuthClient = authClient;\n }\n}\n\n/**\n * Get or create a cached Google Docs service instance.\n */\nexport function getDocsService(authClient: OAuth2Client): docs_v1.Docs {\n checkAuthClient(authClient);\n if (!docsService) {\n docsService = google.docs({ version: \"v1\", auth: authClient });\n }\n return docsService;\n}\n\n/**\n * Get or create a cached Google Sheets service instance.\n */\nexport function getSheetsService(authClient: OAuth2Client): sheets_v4.Sheets {\n checkAuthClient(authClient);\n if (!sheetsService) {\n sheetsService = google.sheets({ version: \"v4\", auth: authClient });\n }\n return sheetsService;\n}\n\n/**\n * Get or create a cached Google Slides service instance.\n */\nexport function getSlidesService(authClient: OAuth2Client): slides_v1.Slides {\n checkAuthClient(authClient);\n if (!slidesService) {\n slidesService = google.slides({ version: \"v1\", auth: authClient });\n }\n return slidesService;\n}\n\n/**\n * Get or create a cached Google Calendar service instance.\n */\nexport function getCalendarService(authClient: OAuth2Client): calendar_v3.Calendar {\n checkAuthClient(authClient);\n if (!calendarService) {\n calendarService = google.calendar({ version: \"v3\", auth: authClient });\n }\n return calendarService;\n}\n\n/**\n * Get or create a cached Gmail service instance.\n */\nexport function getGmailService(authClient: OAuth2Client): gmail_v1.Gmail {\n checkAuthClient(authClient);\n if (!gmailService) {\n gmailService = google.gmail({ version: \"v1\", auth: authClient });\n }\n return gmailService;\n}\n", "/**\n * Timeout wrapper for async operations.\n * Wraps a promise with a timeout to prevent hanging requests.\n */\n\n/** Default timeout for Google API calls (30 seconds) */\nexport const DEFAULT_API_TIMEOUT_MS = 30000;\n\n/**\n * Wraps a promise with a timeout.\n * If the promise doesn't resolve within the specified time, it rejects with a timeout error.\n *\n * @param promise - The promise to wrap\n * @param ms - Timeout in milliseconds (default: 30000)\n * @param operation - Description of the operation for error messages\n * @returns The result of the promise if it resolves in time\n * @throws Error if the operation times out\n */\nexport async function withTimeout<T>(\n promise: Promise<T>,\n ms: number = DEFAULT_API_TIMEOUT_MS,\n operation: string = \"Operation\",\n): Promise<T> {\n let timeoutId: ReturnType<typeof setTimeout>;\n\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n reject(new Error(`${operation} timed out after ${ms}ms`));\n }, ms);\n });\n\n try {\n const result = await Promise.race([promise, timeoutPromise]);\n clearTimeout(timeoutId!);\n return result;\n } catch (error) {\n clearTimeout(timeoutId!);\n throw error;\n }\n}\n", "/**\n * Retry utility with exponential backoff for Google API rate limiting\n */\n\nimport { log } from \"./logging.js\";\n\nexport interface RetryOptions {\n /** Maximum number of retry attempts (default: 5) */\n maxRetries?: number;\n /** Initial delay in milliseconds (default: 1000) */\n initialDelayMs?: number;\n /** Maximum delay in milliseconds (default: 60000) */\n maxDelayMs?: number;\n /** Multiplier for exponential backoff (default: 2) */\n backoffMultiplier?: number;\n /** Jitter factor to add randomness (0-1, default: 0.1) */\n jitterFactor?: number;\n /** Operation name for logging */\n operationName?: string;\n}\n\nexport interface GoogleApiError {\n code?: number;\n status?: number;\n message?: string;\n errors?: Array<{ reason?: string; domain?: string; message?: string }>;\n}\n\nconst DEFAULT_OPTIONS: Required<RetryOptions> = {\n maxRetries: 5,\n initialDelayMs: 1000,\n maxDelayMs: 60000,\n backoffMultiplier: 2,\n jitterFactor: 0.1,\n operationName: \"API call\",\n};\n\n/**\n * HTTP status codes that indicate a retryable error\n */\nconst RETRYABLE_STATUS_CODES = [\n 429, // Too Many Requests (rate limited)\n 500, // Internal Server Error\n 502, // Bad Gateway\n 503, // Service Unavailable\n 504, // Gateway Timeout\n];\n\n/**\n * Google API error reasons that indicate a retryable error\n */\nconst RETRYABLE_REASONS = [\n \"rateLimitExceeded\",\n \"userRateLimitExceeded\",\n \"quotaExceeded\",\n \"internalError\",\n \"backendError\",\n];\n\n/**\n * Determines if an error is retryable\n */\nfunction isRetryableError(error: unknown): boolean {\n const apiError = error as GoogleApiError;\n\n // Check HTTP status code\n const statusCode = apiError.code || apiError.status;\n if (statusCode && RETRYABLE_STATUS_CODES.includes(statusCode)) {\n return true;\n }\n\n // Check Google API error reasons\n if (apiError.errors?.length) {\n for (const err of apiError.errors) {\n if (err.reason && RETRYABLE_REASONS.includes(err.reason)) {\n return true;\n }\n }\n }\n\n // Check error message for rate limit indicators\n const message = apiError.message?.toLowerCase() || \"\";\n if (\n message.includes(\"rate limit\") ||\n message.includes(\"quota\") ||\n message.includes(\"too many requests\")\n ) {\n return true;\n }\n\n return false;\n}\n\n/**\n * Calculates the delay for the next retry attempt with exponential backoff and jitter\n */\nfunction calculateDelay(attempt: number, options: Required<RetryOptions>): number {\n // Exponential backoff: initialDelay * (multiplier ^ attempt)\n const exponentialDelay = options.initialDelayMs * Math.pow(options.backoffMultiplier, attempt);\n\n // Cap at max delay\n const cappedDelay = Math.min(exponentialDelay, options.maxDelayMs);\n\n // Add jitter to prevent thundering herd\n const jitter = cappedDelay * options.jitterFactor * Math.random();\n const finalDelay = cappedDelay + jitter;\n\n return Math.floor(finalDelay);\n}\n\n/**\n * Sleep for a given number of milliseconds\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Executes an async operation with automatic retry and exponential backoff\n *\n * @param operation - The async operation to execute\n * @param options - Retry configuration options\n * @returns The result of the operation\n * @throws The last error if all retries are exhausted\n *\n * @example\n * ```typescript\n * const result = await withRetry(\n * () => drive.files.list({ pageSize: 100 }),\n * { operationName: 'listFiles', maxRetries: 3 }\n * );\n * ```\n */\nexport async function withRetry<T>(\n operation: () => Promise<T>,\n options: RetryOptions = {},\n): Promise<T> {\n const config = { ...DEFAULT_OPTIONS, ...options };\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= config.maxRetries; attempt++) {\n try {\n return await operation();\n } catch (error) {\n lastError = error;\n\n // Check if we should retry\n if (attempt >= config.maxRetries) {\n log(`${config.operationName} failed after ${config.maxRetries + 1} attempts`, {\n error: error instanceof Error ? error.message : String(error),\n });\n throw error;\n }\n\n if (!isRetryableError(error)) {\n log(`${config.operationName} failed with non-retryable error`, {\n error: error instanceof Error ? error.message : String(error),\n });\n throw error;\n }\n\n // Calculate delay and wait\n const delayMs = calculateDelay(attempt, config);\n log(`${config.operationName} failed, retrying in ${delayMs}ms`, {\n attempt: attempt + 1,\n maxRetries: config.maxRetries,\n error: error instanceof Error ? error.message : String(error),\n });\n\n await sleep(delayMs);\n }\n }\n\n throw lastError;\n}\n\n/**\n * Creates a retry wrapper with preset options\n *\n * @param defaultOptions - Default options for all retry operations\n * @returns A retry function with preset options\n *\n * @example\n * ```typescript\n * const retryWithDefaults = createRetryWrapper({ maxRetries: 3 });\n * const result = await retryWithDefaults(\n * () => drive.files.get({ fileId: '123' }),\n * { operationName: 'getFile' }\n * );\n * ```\n */\nexport function createRetryWrapper(defaultOptions: RetryOptions) {\n return async function <T>(operation: () => Promise<T>, options: RetryOptions = {}): Promise<T> {\n return withRetry(operation, { ...defaultOptions, ...options });\n };\n}\n\n/**\n * Batch operation processor with rate limiting\n *\n * Processes items in parallel with a configurable concurrency limit\n * to avoid overwhelming the Google API.\n *\n * @param items - Items to process\n * @param processor - Function to process each item\n * @param options - Configuration options\n * @returns Results for each item (success or error)\n */\nexport async function withRateLimitedBatch<T, R>(\n items: T[],\n processor: (item: T) => Promise<R>,\n options: {\n /** Maximum concurrent operations (default: 5) */\n concurrency?: number;\n /** Delay between batches in ms (default: 100) */\n batchDelayMs?: number;\n /** Operation name for logging */\n operationName?: string;\n } = {},\n): Promise<Array<{ success: true; result: R } | { success: false; error: string }>> {\n const { concurrency = 5, batchDelayMs = 100, operationName = \"batch operation\" } = options;\n\n const results: Array<{ success: true; result: R } | { success: false; error: string }> = [];\n\n // Process in batches\n for (let i = 0; i < items.length; i += concurrency) {\n const batch = items.slice(i, i + concurrency);\n\n log(`Processing ${operationName} batch`, {\n batchStart: i,\n batchSize: batch.length,\n totalItems: items.length,\n });\n\n const batchResults = await Promise.all(\n batch.map(\n async (item): Promise<{ success: true; result: R } | { success: false; error: string }> => {\n try {\n const result = await withRetry(() => processor(item), {\n operationName,\n maxRetries: 3,\n });\n return { success: true, result };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n },\n ),\n );\n\n results.push(...batchResults);\n\n // Add delay between batches to avoid rate limits\n if (i + concurrency < items.length) {\n await sleep(batchDelayMs);\n }\n }\n\n return results;\n}\n", "/**\n * Elicitation utilities for interactive disambiguation\n *\n * Elicitation allows the server to pause and request additional information\n * from the user during tool execution. This is useful for:\n * - File selection when multiple files match\n * - Confirmation of destructive operations\n * - Requesting missing required parameters\n *\n * When the client doesn't support elicitation, these functions fall back\n * to returning structured responses that prompt the user to retry with\n * more specific parameters.\n */\n\nimport type { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { log } from \"./logging.js\";\n\nexport interface FileOption {\n id: string;\n name: string;\n mimeType?: string;\n modifiedTime?: string;\n path?: string;\n}\n\nexport interface ElicitFileSelectionResult {\n selectedFileId: string | null;\n cancelled: boolean;\n error?: string;\n}\n\nexport interface ElicitConfirmationResult {\n confirmed: boolean;\n cancelled: boolean;\n}\n\n/**\n * Check if the server's connected client supports form elicitation\n */\nexport function supportsFormElicitation(server: Server): boolean {\n // Access the private _clientCapabilities field\n const serverAny = server as unknown as {\n _clientCapabilities?: { elicitation?: { form?: boolean } };\n };\n return !!serverAny._clientCapabilities?.elicitation?.form;\n}\n\n/**\n * Elicit file selection from the user when multiple files match\n *\n * @param server - The MCP server instance\n * @param files - List of matching files to choose from\n * @param message - Optional message to display to the user\n * @returns Selected file ID or null if cancelled/unsupported\n */\nexport async function elicitFileSelection(\n server: Server,\n files: FileOption[],\n message?: string,\n): Promise<ElicitFileSelectionResult> {\n if (files.length === 0) {\n return {\n selectedFileId: null,\n cancelled: false,\n error: \"No files to select from\",\n };\n }\n\n if (files.length === 1) {\n return { selectedFileId: files[0].id, cancelled: false };\n }\n\n // Check if client supports elicitation\n if (!supportsFormElicitation(server)) {\n log(\"Client does not support elicitation, returning file list\");\n return {\n selectedFileId: null,\n cancelled: false,\n error: buildFileSelectionFallbackMessage(files, message),\n };\n }\n\n try {\n // Build enum values from file options\n const enumValues = files.map((f) => f.id);\n\n const result = await server.elicitInput({\n mode: \"form\",\n message: message || \"Multiple files found. Please select one:\",\n requestedSchema: {\n type: \"object\",\n properties: {\n selectedFile: {\n type: \"string\",\n title: \"Select File\",\n description: \"Choose which file to use\",\n enum: enumValues,\n // Note: enumLabels is not standard JSON Schema but some clients may support it\n },\n },\n required: [\"selectedFile\"],\n },\n });\n\n if (result.action === \"accept\" && result.content) {\n const content = result.content as { selectedFile?: string };\n return {\n selectedFileId: content.selectedFile || null,\n cancelled: false,\n };\n }\n\n return { selectedFileId: null, cancelled: true };\n } catch (error) {\n log(\"Elicitation failed\", { error: error instanceof Error ? error.message : String(error) });\n return {\n selectedFileId: null,\n cancelled: false,\n error: buildFileSelectionFallbackMessage(files, message),\n };\n }\n}\n\n/**\n * Elicit confirmation for a potentially destructive operation\n *\n * @param server - The MCP server instance\n * @param message - Description of the operation to confirm\n * @param details - Optional additional details about the operation\n * @returns Whether the user confirmed or cancelled\n */\nexport async function elicitConfirmation(\n server: Server,\n message: string,\n details?: string,\n): Promise<ElicitConfirmationResult> {\n if (!supportsFormElicitation(server)) {\n log(\"Client does not support elicitation for confirmation\");\n return { confirmed: false, cancelled: false };\n }\n\n try {\n const fullMessage = details ? `${message}\\n\\nDetails: ${details}` : message;\n\n const result = await server.elicitInput({\n mode: \"form\",\n message: fullMessage,\n requestedSchema: {\n type: \"object\",\n properties: {\n confirm: {\n type: \"boolean\",\n title: \"Confirm\",\n description: \"Check to confirm this operation\",\n default: false,\n },\n },\n required: [\"confirm\"],\n },\n });\n\n if (result.action === \"accept\" && result.content) {\n const content = result.content as { confirm?: boolean };\n return { confirmed: !!content.confirm, cancelled: false };\n }\n\n return { confirmed: false, cancelled: true };\n } catch (error) {\n log(\"Confirmation elicitation failed\", {\n error: error instanceof Error ? error.message : String(error),\n });\n return { confirmed: false, cancelled: false };\n }\n}\n\n/**\n * Build a fallback message for file selection when elicitation is not available\n */\nfunction buildFileSelectionFallbackMessage(files: FileOption[], message?: string): string {\n const header =\n message ||\n \"Multiple files found with that name. Please specify which one by using the file ID:\";\n\n const fileList = files\n .map((f, i) => {\n let entry = `${i + 1}. \"${f.name}\" (ID: ${f.id})`;\n if (f.mimeType) {\n entry += `\\n Type: ${f.mimeType}`;\n }\n if (f.modifiedTime) {\n entry += `\\n Modified: ${new Date(f.modifiedTime).toLocaleString()}`;\n }\n if (f.path) {\n entry += `\\n Path: ${f.path}`;\n }\n return entry;\n })\n .join(\"\\n\\n\");\n\n return `${header}\\n\\n${fileList}\\n\\nPlease retry with the specific file ID.`;\n}\n\n/**\n * Format disambiguation options for non-elicitation fallback\n */\nexport function formatDisambiguationOptions(\n files: Array<{\n id: string;\n name: string;\n mimeType?: string;\n modifiedTime?: string | null;\n parents?: string[];\n }>,\n contextMessage: string,\n): string {\n const options = files\n .map((f, i) => {\n const modified = f.modifiedTime\n ? ` (modified: ${new Date(f.modifiedTime).toLocaleDateString()})`\n : \"\";\n const type = f.mimeType ? ` [${f.mimeType.split(\".\").pop() || f.mimeType}]` : \"\";\n return `${i + 1}. ${f.name}${type}${modified}\\n ID: ${f.id}`;\n })\n .join(\"\\n\\n\");\n\n return `${contextMessage}\\n\\n${options}\\n\\nTo proceed, please specify the file ID directly.`;\n}\n", "/**\n * Progress notification utilities for long-running operations\n *\n * MCP supports out-of-band progress notifications that allow servers\n * to report progress on long-running operations back to the client.\n *\n * Progress notifications require:\n * 1. The client to include a progressToken in their request\n * 2. The server to send notifications/progress with that token\n */\n\nimport type { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { log } from \"./logging.js\";\n\nexport interface ProgressReporter {\n /**\n * Report progress to the client\n * @param progress - Current progress count\n * @param total - Optional total count (if known)\n * @param message - Optional status message\n */\n report(progress: number, total?: number, message?: string): Promise<void>;\n\n /**\n * Check if progress reporting is available\n */\n isAvailable(): boolean;\n}\n\n/**\n * Create a progress reporter for a given operation\n *\n * @param server - The MCP server instance\n * @param progressToken - The progress token from the client request (if any)\n * @returns A ProgressReporter that can be used to send progress updates\n *\n * @example\n * ```typescript\n * const reporter = createProgressReporter(server, request.params._meta?.progressToken);\n *\n * for (let i = 0; i < items.length; i++) {\n * await processItem(items[i]);\n * await reporter.report(i + 1, items.length, `Processing ${items[i].name}`);\n * }\n * ```\n */\nexport function createProgressReporter(\n server: Server,\n progressToken?: string | number,\n): ProgressReporter {\n // Access the notification method on the server\n // The Server class has a notification method inherited from Protocol\n const serverAny = server as unknown as {\n notification(notification: { method: string; params: unknown }): Promise<void>;\n };\n\n const canReport = !!progressToken;\n\n return {\n isAvailable(): boolean {\n return canReport;\n },\n\n async report(progress: number, total?: number, message?: string): Promise<void> {\n if (!canReport) {\n return;\n }\n\n try {\n await serverAny.notification({\n method: \"notifications/progress\",\n params: {\n progressToken,\n progress,\n ...(total !== undefined && { total }),\n ...(message !== undefined && { message }),\n },\n });\n } catch (error) {\n // Log but don't fail the operation if progress notification fails\n log(\"Failed to send progress notification\", {\n error: error instanceof Error ? error.message : String(error),\n progress,\n total,\n message,\n });\n }\n },\n };\n}\n\n/**\n * Options for batch processing with progress\n */\nexport interface BatchWithProgressOptions<T, R> {\n /** The MCP server instance */\n server: Server;\n /** Progress token from the client request */\n progressToken?: string | number;\n /** Items to process */\n items: T[];\n /** Function to process each item */\n processor: (item: T, index: number) => Promise<R>;\n /** Maximum concurrent operations (default: 5) */\n concurrency?: number;\n /** Operation name for progress messages */\n operationName?: string;\n}\n\n/**\n * Process items in batches with progress reporting\n *\n * @returns Results for each item with success/error status\n *\n * @example\n * ```typescript\n * const results = await processBatchWithProgress({\n * server,\n * progressToken: request.params._meta?.progressToken,\n * items: fileIds,\n * processor: async (fileId) => {\n * await drive.files.trash({ fileId });\n * return { fileId };\n * },\n * operationName: 'Deleting files'\n * });\n * ```\n */\nexport async function processBatchWithProgress<T, R>(\n options: BatchWithProgressOptions<T, R>,\n): Promise<Array<{ success: true; result: R } | { success: false; error: string; item: T }>> {\n const {\n server,\n progressToken,\n items,\n processor,\n concurrency = 5,\n operationName = \"Processing\",\n } = options;\n\n const reporter = createProgressReporter(server, progressToken);\n const results: Array<{ success: true; result: R } | { success: false; error: string; item: T }> =\n [];\n let completed = 0;\n\n // Report initial progress\n if (reporter.isAvailable()) {\n await reporter.report(0, items.length, `Starting ${operationName}...`);\n }\n\n // Process in batches\n for (let i = 0; i < items.length; i += concurrency) {\n const batch = items.slice(i, i + concurrency);\n\n const batchResults = await Promise.all(\n batch.map(\n async (\n item,\n batchIndex,\n ): Promise<{ success: true; result: R } | { success: false; error: string; item: T }> => {\n const index = i + batchIndex;\n try {\n const result = await processor(item, index);\n return { success: true, result };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n item,\n };\n }\n },\n ),\n );\n\n results.push(...batchResults);\n completed += batch.length;\n\n // Report progress after each batch\n if (reporter.isAvailable()) {\n await reporter.report(\n completed,\n items.length,\n `${operationName}: ${completed}/${items.length} complete`,\n );\n }\n }\n\n // Report completion\n if (reporter.isAvailable()) {\n const successCount = results.filter((r) => r.success).length;\n const failCount = results.filter((r) => !r.success).length;\n await reporter.report(\n items.length,\n items.length,\n `${operationName} complete: ${successCount} succeeded, ${failCount} failed`,\n );\n }\n\n return results;\n}\n\n/**\n * Wrap a long-running operation with progress reporting\n *\n * Useful for operations that have intermediate steps you want to report on\n *\n * @example\n * ```typescript\n * const result = await withProgressReporting(\n * server,\n * progressToken,\n * async (report) => {\n * await report(1, 3, 'Step 1: Preparing...');\n * // ... do step 1\n *\n * await report(2, 3, 'Step 2: Processing...');\n * // ... do step 2\n *\n * await report(3, 3, 'Step 3: Finalizing...');\n * // ... do step 3\n *\n * return finalResult;\n * }\n * );\n * ```\n */\nexport async function withProgressReporting<T>(\n server: Server,\n progressToken: string | number | undefined,\n operation: (\n report: (progress: number, total?: number, message?: string) => Promise<void>,\n ) => Promise<T>,\n): Promise<T> {\n const reporter = createProgressReporter(server, progressToken);\n return operation((progress, total, message) => reporter.report(progress, total, message));\n}\n", "/**\n * Simple in-memory cache for path resolution.\n * Caches both full paths and intermediate segment lookups to avoid redundant API calls.\n */\n\ninterface CacheEntry {\n fileId: string;\n timestamp: number;\n}\n\nconst TTL_MS = 60_000; // 60-second cache TTL\n\n// Cache for full paths: \"/foo/bar\" -> fileId\nconst pathCache = new Map<string, CacheEntry>();\n\n// Cache for segment lookups: \"parentId:segmentName\" -> fileId\nconst segmentCache = new Map<string, CacheEntry>();\n\nfunction isExpired(entry: CacheEntry): boolean {\n return Date.now() - entry.timestamp > TTL_MS;\n}\n\n/**\n * Get a cached full path resolution.\n * @param path - The full path (e.g., \"/Documents/Projects\")\n * @returns The cached fileId or undefined if not cached/expired\n */\nexport function getCachedPath(path: string): string | undefined {\n const normalized = normalizePath(path);\n const entry = pathCache.get(normalized);\n if (!entry) return undefined;\n\n if (isExpired(entry)) {\n pathCache.delete(normalized);\n return undefined;\n }\n\n return entry.fileId;\n}\n\n/**\n * Cache a full path resolution.\n * @param path - The full path\n * @param fileId - The resolved file ID\n */\nexport function setCachedPath(path: string, fileId: string): void {\n const normalized = normalizePath(path);\n pathCache.set(normalized, { fileId, timestamp: Date.now() });\n}\n\n/**\n * Get a cached segment lookup.\n * @param parentId - The parent folder ID\n * @param segmentName - The folder/file name to look up\n * @returns The cached fileId or undefined if not cached/expired\n */\nexport function getCachedSegment(parentId: string, segmentName: string): string | undefined {\n const key = `${parentId}:${segmentName}`;\n const entry = segmentCache.get(key);\n if (!entry) return undefined;\n\n if (isExpired(entry)) {\n segmentCache.delete(key);\n return undefined;\n }\n\n return entry.fileId;\n}\n\n/**\n * Cache a segment lookup.\n * @param parentId - The parent folder ID\n * @param segmentName - The folder/file name\n * @param fileId - The resolved file ID\n */\nexport function setCachedSegment(parentId: string, segmentName: string, fileId: string): void {\n const key = `${parentId}:${segmentName}`;\n segmentCache.set(key, { fileId, timestamp: Date.now() });\n}\n\n/**\n * Clear the path cache.\n * @param path - Optional specific path to clear. If not provided, clears all.\n */\nexport function clearPathCache(path?: string): void {\n if (path) {\n const normalized = normalizePath(path);\n pathCache.delete(normalized);\n } else {\n pathCache.clear();\n segmentCache.clear();\n }\n}\n\n/**\n * Get cache statistics for debugging.\n */\nexport function getPathCacheStats(): { pathCount: number; segmentCount: number } {\n return {\n pathCount: pathCache.size,\n segmentCount: segmentCache.size,\n };\n}\n\n/**\n * Clean up expired cache entries.\n * Call periodically to prevent memory leaks in long-running sessions.\n * @returns Number of entries removed\n */\nexport function cleanupExpiredCache(): number {\n let removed = 0;\n const now = Date.now();\n\n for (const [key, entry] of pathCache.entries()) {\n if (now - entry.timestamp > TTL_MS) {\n pathCache.delete(key);\n removed++;\n }\n }\n\n for (const [key, entry] of segmentCache.entries()) {\n if (now - entry.timestamp > TTL_MS) {\n segmentCache.delete(key);\n removed++;\n }\n }\n\n return removed;\n}\n\n/**\n * Normalize a path for consistent caching.\n */\nfunction normalizePath(path: string): string {\n return path.replace(/^\\/+|\\/+$/g, \"\").toLowerCase();\n}\n", "/**\n * MIME message construction utilities for Gmail API.\n * Gmail requires raw email content to be base64url encoded.\n */\n\nexport interface EmailOptions {\n to: string[];\n subject: string;\n body: string;\n html?: string;\n cc?: string[];\n bcc?: string[];\n replyTo?: string;\n attachments?: Array<{\n filename: string;\n content: string; // Base64 encoded\n mimeType?: string;\n }>;\n inReplyTo?: string;\n references?: string;\n}\n\n/**\n * Generate a random boundary for multipart messages\n */\nfunction generateBoundary(): string {\n return `----=_Part_${Date.now()}_${Math.random().toString(36).substring(2)}`;\n}\n\n/**\n * Detect MIME type from filename extension\n */\nfunction detectMimeType(filename: string): string {\n const ext = filename.split(\".\").pop()?.toLowerCase();\n const mimeTypes: Record<string, string> = {\n txt: \"text/plain\",\n html: \"text/html\",\n htm: \"text/html\",\n css: \"text/css\",\n js: \"application/javascript\",\n json: \"application/json\",\n xml: \"application/xml\",\n pdf: \"application/pdf\",\n zip: \"application/zip\",\n gz: \"application/gzip\",\n tar: \"application/x-tar\",\n doc: \"application/msword\",\n docx: \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n xls: \"application/vnd.ms-excel\",\n xlsx: \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n ppt: \"application/vnd.ms-powerpoint\",\n pptx: \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\n png: \"image/png\",\n jpg: \"image/jpeg\",\n jpeg: \"image/jpeg\",\n gif: \"image/gif\",\n svg: \"image/svg+xml\",\n webp: \"image/webp\",\n ico: \"image/x-icon\",\n mp3: \"audio/mpeg\",\n wav: \"audio/wav\",\n mp4: \"video/mp4\",\n webm: \"video/webm\",\n avi: \"video/x-msvideo\",\n mov: \"video/quicktime\",\n csv: \"text/csv\",\n md: \"text/markdown\",\n };\n return mimeTypes[ext || \"\"] || \"application/octet-stream\";\n}\n\n/**\n * Build a MIME message for Gmail API.\n * Returns a base64url-encoded string ready for the Gmail API.\n */\nexport function buildMimeMessage(options: EmailOptions): string {\n const { to, subject, body, html, cc, bcc, replyTo, attachments, inReplyTo, references } = options;\n\n const hasHtml = !!html;\n const hasAttachments = attachments && attachments.length > 0;\n\n // Build headers\n const headers: string[] = [\n `To: ${to.join(\", \")}`,\n `Subject: =?UTF-8?B?${Buffer.from(subject).toString(\"base64\")}?=`,\n \"MIME-Version: 1.0\",\n ];\n\n if (cc && cc.length > 0) {\n headers.push(`Cc: ${cc.join(\", \")}`);\n }\n\n if (bcc && bcc.length > 0) {\n headers.push(`Bcc: ${bcc.join(\", \")}`);\n }\n\n if (replyTo) {\n headers.push(`Reply-To: ${replyTo}`);\n }\n\n if (inReplyTo) {\n headers.push(`In-Reply-To: ${inReplyTo}`);\n }\n\n if (references) {\n headers.push(`References: ${references}`);\n }\n\n let messageBody: string;\n\n if (hasAttachments) {\n // Multipart mixed for attachments\n const mixedBoundary = generateBoundary();\n headers.push(`Content-Type: multipart/mixed; boundary=\"${mixedBoundary}\"`);\n\n const parts: string[] = [];\n\n // Text/HTML part\n if (hasHtml) {\n const altBoundary = generateBoundary();\n parts.push(`--${mixedBoundary}`);\n parts.push(`Content-Type: multipart/alternative; boundary=\"${altBoundary}\"`);\n parts.push(\"\");\n parts.push(`--${altBoundary}`);\n parts.push(\"Content-Type: text/plain; charset=UTF-8\");\n parts.push(\"Content-Transfer-Encoding: base64\");\n parts.push(\"\");\n parts.push(Buffer.from(body).toString(\"base64\"));\n parts.push(`--${altBoundary}`);\n parts.push(\"Content-Type: text/html; charset=UTF-8\");\n parts.push(\"Content-Transfer-Encoding: base64\");\n parts.push(\"\");\n parts.push(Buffer.from(html).toString(\"base64\"));\n parts.push(`--${altBoundary}--`);\n } else {\n parts.push(`--${mixedBoundary}`);\n parts.push(\"Content-Type: text/plain; charset=UTF-8\");\n parts.push(\"Content-Transfer-Encoding: base64\");\n parts.push(\"\");\n parts.push(Buffer.from(body).toString(\"base64\"));\n }\n\n // Attachments\n for (const attachment of attachments!) {\n const mimeType = attachment.mimeType || detectMimeType(attachment.filename);\n parts.push(`--${mixedBoundary}`);\n parts.push(`Content-Type: ${mimeType}; name=\"${attachment.filename}\"`);\n parts.push(\"Content-Transfer-Encoding: base64\");\n parts.push(`Content-Disposition: attachment; filename=\"${attachment.filename}\"`);\n parts.push(\"\");\n parts.push(attachment.content);\n }\n\n parts.push(`--${mixedBoundary}--`);\n messageBody = parts.join(\"\\r\\n\");\n } else if (hasHtml) {\n // Multipart alternative for HTML + plain text\n const altBoundary = generateBoundary();\n headers.push(`Content-Type: multipart/alternative; boundary=\"${altBoundary}\"`);\n\n messageBody = [\n `--${altBoundary}`,\n \"Content-Type: text/plain; charset=UTF-8\",\n \"Content-Transfer-Encoding: base64\",\n \"\",\n Buffer.from(body).toString(\"base64\"),\n `--${altBoundary}`,\n \"Content-Type: text/html; charset=UTF-8\",\n \"Content-Transfer-Encoding: base64\",\n \"\",\n Buffer.from(html).toString(\"base64\"),\n `--${altBoundary}--`,\n ].join(\"\\r\\n\");\n } else {\n // Simple plain text\n headers.push(\"Content-Type: text/plain; charset=UTF-8\");\n headers.push(\"Content-Transfer-Encoding: base64\");\n messageBody = Buffer.from(body).toString(\"base64\");\n }\n\n const fullMessage = headers.join(\"\\r\\n\") + \"\\r\\n\\r\\n\" + messageBody;\n\n // Gmail API requires base64url encoding (not standard base64)\n return Buffer.from(fullMessage)\n .toString(\"base64\")\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/, \"\");\n}\n\n/**\n * Parse email headers from a Gmail message payload\n */\nexport function parseEmailHeaders(\n headers: Array<{ name?: string | null; value?: string | null }>,\n): Record<string, string> {\n const result: Record<string, string> = {};\n for (const header of headers) {\n if (header.name && header.value) {\n result[header.name.toLowerCase()] = header.value;\n }\n }\n return result;\n}\n\n/**\n * Decode base64url-encoded content (as used by Gmail API)\n */\nexport function decodeBase64Url(data: string): string {\n // Convert base64url to standard base64\n const base64 = data.replace(/-/g, \"+\").replace(/_/g, \"/\");\n // Add padding if needed\n const padded = base64 + \"=\".repeat((4 - (base64.length % 4)) % 4);\n return Buffer.from(padded, \"base64\").toString(\"utf-8\");\n}\n", "export { log } from \"./logging.js\";\nexport {\n successResponse,\n structuredResponse,\n errorResponse,\n truncateResponse,\n} from \"./responses.js\";\nexport type { ToolResponse, ErrorCode, ErrorOptions, TruncationResult } from \"./responses.js\";\nexport { validateArgs } from \"./validation.js\";\nexport type { ValidationResult } from \"./validation.js\";\nexport {\n getDocsService,\n getSheetsService,\n getSlidesService,\n getCalendarService,\n getGmailService,\n clearServiceCache,\n} from \"./services.js\";\nexport { withTimeout, DEFAULT_API_TIMEOUT_MS } from \"./timeout.js\";\nexport { withRetry, createRetryWrapper, withRateLimitedBatch } from \"./retry.js\";\nexport type { RetryOptions, GoogleApiError } from \"./retry.js\";\nexport {\n elicitFileSelection,\n elicitConfirmation,\n supportsFormElicitation,\n formatDisambiguationOptions,\n} from \"./elicitation.js\";\nexport type {\n FileOption,\n ElicitFileSelectionResult,\n ElicitConfirmationResult,\n} from \"./elicitation.js\";\nexport {\n createProgressReporter,\n processBatchWithProgress,\n withProgressReporting,\n} from \"./progress.js\";\nexport type { ProgressReporter, BatchWithProgressOptions } from \"./progress.js\";\nexport {\n getCachedPath,\n setCachedPath,\n getCachedSegment,\n setCachedSegment,\n clearPathCache,\n getPathCacheStats,\n cleanupExpiredCache,\n} from \"./pathCache.js\";\nexport { buildMimeMessage, parseEmailHeaders, decodeBase64Url } from \"./mime.js\";\nexport type { EmailOptions } from \"./mime.js\";\n", "#!/usr/bin/env node\n\nimport { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport {\n CallToolRequestSchema,\n ListResourcesRequestSchema,\n ListToolsRequestSchema,\n ReadResourceRequestSchema,\n ListPromptsRequestSchema,\n GetPromptRequestSchema,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { google } from \"googleapis\";\nimport type { drive_v3 } from \"googleapis\";\nimport { authenticate, AuthServer, initializeOAuth2Client } from \"./auth.js\";\nimport type { OAuth2Client } from \"google-auth-library\";\nimport { fileURLToPath } from \"url\";\nimport { readFileSync } from \"fs\";\nimport { join, dirname } from \"path\";\n\n// Import utilities\nimport {\n log,\n errorResponse,\n getDocsService,\n getSheetsService,\n getSlidesService,\n getCalendarService,\n getGmailService,\n} from \"./utils/index.js\";\n\n// Import service configuration\nimport { isServiceEnabled, areUnifiedToolsEnabled } from \"./config/index.js\";\n\n// Import all tool definitions\nimport { getAllTools } from \"./tools/index.js\";\n\n// Import prompts\nimport { PROMPTS, generatePromptMessages } from \"./prompts/index.js\";\n\n// Import all handlers\nimport {\n // Drive handlers\n handleSearch,\n handleCreateTextFile,\n handleUpdateTextFile,\n handleCreateFolder,\n handleListFolder,\n handleDeleteItem,\n handleRenameItem,\n handleMoveItem,\n handleCopyFile,\n handleGetFileMetadata,\n handleExportFile,\n handleShareFile,\n handleGetSharing,\n handleListRevisions,\n handleRestoreRevision,\n handleDownloadFile,\n handleUploadFile,\n handleGetStorageQuota,\n handleStarFile,\n handleResolveFilePath,\n handleBatchDelete,\n handleBatchRestore,\n handleBatchMove,\n handleBatchShare,\n handleRemovePermission,\n handleListTrash,\n handleRestoreFromTrash,\n handleEmptyTrash,\n handleGetFolderTree,\n // Docs handlers\n handleCreateGoogleDoc,\n handleUpdateGoogleDoc,\n handleGetGoogleDocContent,\n handleAppendToDoc,\n handleInsertTextInDoc,\n handleDeleteTextInDoc,\n handleReplaceTextInDoc,\n handleFormatGoogleDocRange,\n // Sheets handlers\n handleCreateGoogleSheet,\n handleUpdateGoogleSheet,\n handleGetGoogleSheetContent,\n handleFormatGoogleSheetCells,\n handleMergeGoogleSheetCells,\n handleAddGoogleSheetConditionalFormat,\n handleSheetTabs,\n // Slides handlers\n handleCreateGoogleSlides,\n handleUpdateGoogleSlides,\n handleGetGoogleSlidesContent,\n handleCreateGoogleSlidesTextBox,\n handleCreateGoogleSlidesShape,\n handleSlidesSpeakerNotes,\n handleFormatSlidesText,\n handleFormatSlidesShape,\n handleFormatSlideBackground,\n handleListSlidePages,\n // Unified handlers\n handleCreateFile,\n handleUpdateFile,\n handleGetFileContent,\n // Calendar handlers\n handleListCalendars,\n handleListEvents,\n handleGetEvent,\n handleCreateEvent,\n handleUpdateEvent,\n handleDeleteEvent,\n handleFindFreeTime,\n // Gmail handlers\n handleSendEmail,\n handleDraftEmail,\n handleReadEmail,\n handleSearchEmails,\n handleDeleteEmail,\n handleModifyEmail,\n handleDownloadAttachment,\n handleCreateLabel,\n handleUpdateLabel,\n handleDeleteLabel,\n handleListLabels,\n handleGetOrCreateLabel,\n handleCreateFilter,\n handleListFilters,\n handleDeleteFilter,\n // Discovery handlers\n handleListTools,\n} from \"./handlers/index.js\";\nimport type { HandlerContext } from \"./handlers/index.js\";\n\n// -----------------------------------------------------------------------------\n// CONSTANTS & GLOBAL STATE\n// -----------------------------------------------------------------------------\n\n// Drive service - will be created with auth when needed\nlet drive: drive_v3.Drive | null = null;\n\n// Global auth client - will be initialized on first use\nlet authClient: OAuth2Client | null = null;\nlet authenticationPromise: Promise<OAuth2Client> | null = null;\n\n// Get package version\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst packageJsonPath = join(__dirname, \"..\", \"package.json\");\nconst packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\nconst VERSION = packageJson.version;\n\n// -----------------------------------------------------------------------------\n// DRIVE SERVICE HELPER\n// -----------------------------------------------------------------------------\n\nfunction ensureDriveService() {\n if (!authClient) {\n throw new Error(\"Authentication required\");\n }\n\n log(\"About to create drive service\", {\n authClientType: authClient?.constructor?.name,\n hasCredentials: !!authClient.credentials,\n hasAccessToken: !!authClient.credentials?.access_token,\n expiryDate: authClient.credentials?.expiry_date,\n isExpired: authClient.credentials?.expiry_date\n ? Date.now() > authClient.credentials.expiry_date\n : \"no expiry\",\n });\n\n // Create drive service with auth parameter directly\n drive = google.drive({ version: \"v3\", auth: authClient });\n\n log(\"Drive service created/updated\", {\n hasAuth: !!authClient,\n hasCredentials: !!authClient.credentials,\n hasAccessToken: !!authClient.credentials?.access_token,\n });\n}\n\n// Track auth health for debugging\nlet lastAuthError: string | null = null;\n\nasync function verifyAuthHealth(): Promise<boolean> {\n if (!drive) {\n lastAuthError = \"Drive service not initialized\";\n return false;\n }\n\n try {\n const response = await drive.about.get({ fields: \"user\" });\n log(\"Auth verification successful, user:\", response.data.user?.emailAddress);\n lastAuthError = null;\n return true;\n } catch (error: unknown) {\n const err = error as {\n message?: string;\n response?: { status: number; statusText: string };\n };\n lastAuthError = err.message || String(error);\n log(\"WARNING: Auth verification failed:\", lastAuthError);\n if (err.response) {\n log(\"Auth error details:\", {\n status: err.response.status,\n statusText: err.response.statusText,\n });\n }\n return false;\n }\n}\n\n// Export for testing - allows checking last auth error\nexport function getLastAuthError(): string | null {\n return lastAuthError;\n}\n\n// -----------------------------------------------------------------------------\n// SERVER SETUP\n// -----------------------------------------------------------------------------\n\nconst server = new Server(\n {\n name: \"google-workspace-mcp\",\n version: VERSION,\n },\n {\n capabilities: {\n resources: {},\n tools: {\n listChanged: true,\n },\n prompts: {\n listChanged: true,\n },\n },\n },\n);\n\n// -----------------------------------------------------------------------------\n// AUTHENTICATION HELPER\n// -----------------------------------------------------------------------------\n\nasync function ensureAuthenticated() {\n if (!authClient) {\n // If authentication is already in progress, wait for it\n if (authenticationPromise) {\n log(\"Authentication already in progress, waiting...\");\n authClient = await authenticationPromise;\n return;\n }\n\n log(\"Initializing authentication\");\n // Store the promise to prevent concurrent authentication attempts\n authenticationPromise = authenticate();\n\n try {\n authClient = await authenticationPromise;\n log(\"Authentication complete\", {\n authClientType: authClient?.constructor?.name,\n hasCredentials: !!authClient?.credentials,\n hasAccessToken: !!authClient?.credentials?.access_token,\n });\n // Ensure drive service is created with auth\n ensureDriveService();\n\n // Verify auth works by making a test API call (blocking on first auth)\n const healthy = await verifyAuthHealth();\n if (!healthy) {\n log(\"WARNING: Authentication may be broken. Tool calls may fail.\");\n }\n } finally {\n // Clear the promise after completion (success or failure)\n authenticationPromise = null;\n }\n }\n\n // If we already have authClient, ensure drive is up to date\n ensureDriveService();\n}\n\n// -----------------------------------------------------------------------------\n// MCP REQUEST HANDLERS\n// -----------------------------------------------------------------------------\n\nserver.setRequestHandler(ListResourcesRequestSchema, async (request) => {\n await ensureAuthenticated();\n log(\"Handling ListResources request\", { params: request.params });\n const pageSize = 10;\n const params: {\n pageSize: number;\n fields: string;\n pageToken?: string;\n q: string;\n includeItemsFromAllDrives: boolean;\n supportsAllDrives: boolean;\n } = {\n pageSize,\n fields: \"nextPageToken, files(id, name, mimeType)\",\n q: `trashed = false`,\n includeItemsFromAllDrives: true,\n supportsAllDrives: true,\n };\n\n if (request.params?.cursor) {\n params.pageToken = request.params.cursor;\n }\n\n const res = await drive!.files.list(params);\n log(\"Listed files\", { count: res.data.files?.length });\n const files = res.data.files || [];\n\n return {\n resources: files.map((file: drive_v3.Schema$File) => ({\n uri: `gdrive:///${file.id}`,\n mimeType: file.mimeType || \"application/octet-stream\",\n name: file.name || \"Untitled\",\n })),\n nextCursor: res.data.nextPageToken,\n };\n});\n\nserver.setRequestHandler(ReadResourceRequestSchema, async (request) => {\n await ensureAuthenticated();\n log(\"Handling ReadResource request\", { uri: request.params.uri });\n const fileId = request.params.uri.replace(\"gdrive:///\", \"\");\n\n const file = await drive!.files.get({\n fileId,\n fields: \"mimeType\",\n supportsAllDrives: true,\n });\n const mimeType = file.data.mimeType;\n\n if (!mimeType) {\n throw new Error(\"File has no MIME type.\");\n }\n\n if (mimeType.startsWith(\"application/vnd.google-apps\")) {\n // Export logic for Google Docs/Sheets/Slides\n let exportMimeType;\n switch (mimeType) {\n case \"application/vnd.google-apps.document\":\n exportMimeType = \"text/markdown\";\n break;\n case \"application/vnd.google-apps.spreadsheet\":\n exportMimeType = \"text/csv\";\n break;\n case \"application/vnd.google-apps.presentation\":\n exportMimeType = \"text/plain\";\n break;\n case \"application/vnd.google-apps.drawing\":\n exportMimeType = \"image/png\";\n break;\n default:\n exportMimeType = \"text/plain\";\n break;\n }\n\n const res = await drive!.files.export(\n { fileId, mimeType: exportMimeType },\n { responseType: \"text\" },\n );\n\n log(\"Successfully read resource\", { fileId, mimeType });\n return {\n contents: [\n {\n uri: request.params.uri,\n mimeType: exportMimeType,\n text: res.data,\n },\n ],\n };\n } else {\n // Regular file download\n const res = await drive!.files.get(\n { fileId, alt: \"media\", supportsAllDrives: true },\n { responseType: \"arraybuffer\" },\n );\n const contentMime = mimeType || \"application/octet-stream\";\n\n if (contentMime.startsWith(\"text/\") || contentMime === \"application/json\") {\n return {\n contents: [\n {\n uri: request.params.uri,\n mimeType: contentMime,\n text: Buffer.from(res.data as ArrayBuffer).toString(\"utf-8\"),\n },\n ],\n };\n } else {\n return {\n contents: [\n {\n uri: request.params.uri,\n mimeType: contentMime,\n blob: Buffer.from(res.data as ArrayBuffer).toString(\"base64\"),\n },\n ],\n };\n }\n }\n});\n\nserver.setRequestHandler(ListToolsRequestSchema, async () => {\n return { tools: getAllTools() };\n});\n\n// -----------------------------------------------------------------------------\n// PROMPT REQUEST HANDLERS\n// -----------------------------------------------------------------------------\n\nserver.setRequestHandler(ListPromptsRequestSchema, async () => {\n log(\"Handling ListPrompts request\");\n return {\n prompts: PROMPTS.map((prompt) => ({\n name: prompt.name,\n description: prompt.description,\n arguments: prompt.arguments,\n })),\n };\n});\n\nserver.setRequestHandler(GetPromptRequestSchema, async (request) => {\n log(\"Handling GetPrompt request\", { name: request.params.name });\n\n const promptName = request.params.name;\n const promptDef = PROMPTS.find((p) => p.name === promptName);\n\n if (!promptDef) {\n throw new Error(`Unknown prompt: ${promptName}`);\n }\n\n const args = request.params.arguments || {};\n const messages = generatePromptMessages(promptName, args);\n\n return {\n description: promptDef.description,\n messages,\n };\n});\n\n// -----------------------------------------------------------------------------\n// TOOL REGISTRY\n// -----------------------------------------------------------------------------\n\nimport type { ToolResponse } from \"./utils/index.js\";\nimport type { docs_v1, sheets_v4, slides_v1, calendar_v3, gmail_v1 } from \"googleapis\";\n\ninterface ToolServices {\n drive: drive_v3.Drive;\n docs: docs_v1.Docs;\n sheets: sheets_v4.Sheets;\n slides: slides_v1.Slides;\n calendar: calendar_v3.Calendar;\n gmail: gmail_v1.Gmail;\n context: HandlerContext;\n}\n\ntype ToolHandler = (services: ToolServices, args: unknown) => Promise<ToolResponse>;\n\nfunction createToolRegistry(): Record<string, ToolHandler> {\n const registry: Record<string, ToolHandler> = {};\n\n // Discovery tools (always available)\n Object.assign(registry, {\n list_tools: (_services, args) => handleListTools(args),\n } satisfies Record<string, ToolHandler>);\n\n // Drive tools\n if (isServiceEnabled(\"drive\")) {\n Object.assign(registry, {\n search: ({ drive }, args) => handleSearch(drive, args),\n create_text_file: ({ drive }, args) => handleCreateTextFile(drive, args),\n update_text_file: ({ drive }, args) => handleUpdateTextFile(drive, args),\n create_folder: ({ drive }, args) => handleCreateFolder(drive, args),\n list_folder: ({ drive }, args) => handleListFolder(drive, args),\n delete_item: ({ drive }, args) => handleDeleteItem(drive, args),\n rename_item: ({ drive }, args) => handleRenameItem(drive, args),\n move_item: ({ drive }, args) => handleMoveItem(drive, args),\n copy_file: ({ drive }, args) => handleCopyFile(drive, args),\n get_file_metadata: ({ drive }, args) => handleGetFileMetadata(drive, args),\n export_file: ({ drive }, args) => handleExportFile(drive, args),\n share_file: ({ drive }, args) => handleShareFile(drive, args),\n get_sharing: ({ drive }, args) => handleGetSharing(drive, args),\n list_revisions: ({ drive }, args) => handleListRevisions(drive, args),\n restore_revision: ({ drive }, args) => handleRestoreRevision(drive, args),\n download_file: ({ drive }, args) => handleDownloadFile(drive, args),\n upload_file: ({ drive }, args) => handleUploadFile(drive, args),\n get_storage_quota: ({ drive }, args) => handleGetStorageQuota(drive, args),\n star_file: ({ drive }, args) => handleStarFile(drive, args),\n resolve_file_path: ({ drive, context }, args) => handleResolveFilePath(drive, args, context),\n batch_delete: ({ drive, context }, args) => handleBatchDelete(drive, args, context),\n batch_restore: ({ drive, context }, args) => handleBatchRestore(drive, args, context),\n batch_move: ({ drive, context }, args) => handleBatchMove(drive, args, context),\n batch_share: ({ drive, context }, args) => handleBatchShare(drive, args, context),\n remove_permission: ({ drive }, args) => handleRemovePermission(drive, args),\n list_trash: ({ drive }, args) => handleListTrash(drive, args),\n restore_from_trash: ({ drive }, args) => handleRestoreFromTrash(drive, args),\n empty_trash: ({ drive, context }, args) => handleEmptyTrash(drive, args, context),\n get_folder_tree: ({ drive }, args) => handleGetFolderTree(drive, args),\n } satisfies Record<string, ToolHandler>);\n }\n\n // Docs tools\n if (isServiceEnabled(\"docs\")) {\n Object.assign(registry, {\n create_google_doc: ({ drive, docs }, args) => handleCreateGoogleDoc(drive, docs, args),\n update_google_doc: ({ docs }, args) => handleUpdateGoogleDoc(docs, args),\n get_google_doc_content: ({ drive, docs }, args) =>\n handleGetGoogleDocContent(drive, docs, args),\n append_to_doc: ({ docs }, args) => handleAppendToDoc(docs, args),\n insert_text_in_doc: ({ docs }, args) => handleInsertTextInDoc(docs, args),\n delete_text_in_doc: ({ docs }, args) => handleDeleteTextInDoc(docs, args),\n replace_text_in_doc: ({ docs }, args) => handleReplaceTextInDoc(docs, args),\n format_google_doc_range: ({ docs }, args) => handleFormatGoogleDocRange(docs, args),\n } satisfies Record<string, ToolHandler>);\n }\n\n // Sheets tools\n if (isServiceEnabled(\"sheets\")) {\n Object.assign(registry, {\n create_google_sheet: ({ drive, sheets }, args) =>\n handleCreateGoogleSheet(drive, sheets, args),\n update_google_sheet: ({ sheets }, args) => handleUpdateGoogleSheet(sheets, args),\n get_google_sheet_content: ({ drive, sheets }, args) =>\n handleGetGoogleSheetContent(drive, sheets, args),\n format_google_sheet_cells: ({ sheets }, args) => handleFormatGoogleSheetCells(sheets, args),\n merge_google_sheet_cells: ({ sheets }, args) => handleMergeGoogleSheetCells(sheets, args),\n add_google_sheet_conditional_format: ({ sheets }, args) =>\n handleAddGoogleSheetConditionalFormat(sheets, args),\n sheet_tabs: ({ sheets }, args) => handleSheetTabs(sheets, args),\n } satisfies Record<string, ToolHandler>);\n }\n\n // Slides tools\n if (isServiceEnabled(\"slides\")) {\n Object.assign(registry, {\n create_google_slides: ({ drive, slides }, args) =>\n handleCreateGoogleSlides(drive, slides, args),\n update_google_slides: ({ slides }, args) => handleUpdateGoogleSlides(slides, args),\n get_google_slides_content: ({ drive, slides }, args) =>\n handleGetGoogleSlidesContent(drive, slides, args),\n create_google_slides_text_box: ({ slides }, args) =>\n handleCreateGoogleSlidesTextBox(slides, args),\n create_google_slides_shape: ({ slides }, args) => handleCreateGoogleSlidesShape(slides, args),\n slides_speaker_notes: ({ slides }, args) => handleSlidesSpeakerNotes(slides, args),\n format_slides_text: ({ slides }, args) => handleFormatSlidesText(slides, args),\n format_slides_shape: ({ slides }, args) => handleFormatSlidesShape(slides, args),\n format_slide_background: ({ slides }, args) => handleFormatSlideBackground(slides, args),\n list_slide_pages: ({ slides }, args) => handleListSlidePages(slides, args),\n } satisfies Record<string, ToolHandler>);\n }\n\n // Unified smart tools (require drive+docs+sheets+slides)\n if (areUnifiedToolsEnabled()) {\n Object.assign(registry, {\n create_file: ({ drive, docs, sheets, slides }, args) =>\n handleCreateFile(drive, docs, sheets, slides, args),\n update_file: ({ drive, docs, sheets, slides }, args) =>\n handleUpdateFile(drive, docs, sheets, slides, args),\n get_file_content: ({ drive, docs, sheets, slides }, args) =>\n handleGetFileContent(drive, docs, sheets, slides, args),\n } satisfies Record<string, ToolHandler>);\n }\n\n // Calendar tools\n if (isServiceEnabled(\"calendar\")) {\n Object.assign(registry, {\n list_calendars: ({ calendar }, args) => handleListCalendars(calendar, args),\n list_events: ({ calendar }, args) => handleListEvents(calendar, args),\n get_event: ({ calendar }, args) => handleGetEvent(calendar, args),\n create_event: ({ calendar }, args) => handleCreateEvent(calendar, args),\n update_event: ({ calendar }, args) => handleUpdateEvent(calendar, args),\n delete_event: ({ calendar }, args) => handleDeleteEvent(calendar, args),\n find_free_time: ({ calendar }, args) => handleFindFreeTime(calendar, args),\n } satisfies Record<string, ToolHandler>);\n }\n\n // Gmail tools\n if (isServiceEnabled(\"gmail\")) {\n Object.assign(registry, {\n send_email: ({ gmail }, args) => handleSendEmail(gmail, args),\n draft_email: ({ gmail }, args) => handleDraftEmail(gmail, args),\n read_email: ({ gmail }, args) => handleReadEmail(gmail, args),\n search_emails: ({ gmail }, args) => handleSearchEmails(gmail, args),\n delete_email: ({ gmail }, args) => handleDeleteEmail(gmail, args),\n modify_email: ({ gmail }, args) => handleModifyEmail(gmail, args),\n download_attachment: ({ gmail }, args) => handleDownloadAttachment(gmail, args),\n create_label: ({ gmail }, args) => handleCreateLabel(gmail, args),\n update_label: ({ gmail }, args) => handleUpdateLabel(gmail, args),\n delete_label: ({ gmail }, args) => handleDeleteLabel(gmail, args),\n list_labels: ({ gmail }, args) => handleListLabels(gmail, args),\n get_or_create_label: ({ gmail }, args) => handleGetOrCreateLabel(gmail, args),\n create_filter: ({ gmail }, args) => handleCreateFilter(gmail, args),\n list_filters: ({ gmail }, args) => handleListFilters(gmail, args),\n delete_filter: ({ gmail }, args) => handleDeleteFilter(gmail, args),\n } satisfies Record<string, ToolHandler>);\n }\n\n return registry;\n}\n\nconst toolRegistry = createToolRegistry();\n\n// -----------------------------------------------------------------------------\n// TOOL CALL REQUEST HANDLER\n// -----------------------------------------------------------------------------\n\nserver.setRequestHandler(CallToolRequestSchema, async (request) => {\n await ensureAuthenticated();\n log(\"Handling tool request\", { tool: request.params.name });\n\n try {\n const args = request.params.arguments;\n const meta = (request.params as { _meta?: { progressToken?: string | number } })._meta;\n\n const services: ToolServices = {\n drive: drive!,\n docs: getDocsService(authClient!),\n sheets: getSheetsService(authClient!),\n slides: getSlidesService(authClient!),\n calendar: getCalendarService(authClient!),\n gmail: getGmailService(authClient!),\n context: { server, progressToken: meta?.progressToken },\n };\n\n const handler = toolRegistry[request.params.name];\n if (!handler) {\n return errorResponse(`Unknown tool: ${request.params.name}`);\n }\n\n return handler(services, args);\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n log(\"Tool error\", { error: message });\n return errorResponse(message);\n }\n});\n\n// -----------------------------------------------------------------------------\n// CLI HELPER FUNCTIONS\n// -----------------------------------------------------------------------------\n\nfunction showHelp(): void {\n console.log(`\nGoogle Workspace MCP Server v${VERSION}\n\nUsage:\n npx @dguido/google-workspace-mcp [command] [options]\n\nCommands:\n auth Run the authentication flow\n start Start the MCP server (default)\n version Show version information\n help Show this help message\n\nAuth Options:\n --token-path <path> Save tokens to custom path (e.g., .credentials/tokens.json)\n --credentials-path <path> Use custom OAuth credentials file\n\nExamples:\n npx @dguido/google-workspace-mcp auth\n npx @dguido/google-workspace-mcp auth --token-path .credentials/tokens.json\n npx @dguido/google-workspace-mcp auth \\\\\n --credentials-path .credentials/gcp-oauth.keys.json \\\\\n --token-path .credentials/tokens.json\n npx @dguido/google-workspace-mcp start\n npx @dguido/google-workspace-mcp\n\nEnvironment Variables:\n GOOGLE_DRIVE_OAUTH_CREDENTIALS Path to OAuth credentials file\n GOOGLE_WORKSPACE_MCP_TOKEN_PATH Path to store authentication tokens\n\nMulti-Account Setup:\n For project-level credential storage (useful with multiple Google accounts):\n 1. Create a .credentials directory in your project\n 2. Use CLI flags or env vars to point to project-level paths\n 3. Add .credentials/ to your .gitignore\n`);\n}\n\nfunction showVersion(): void {\n console.log(`Google Workspace MCP Server v${VERSION}`);\n}\n\nasync function runAuthServer(tokenPath?: string, credentialsPath?: string): Promise<void> {\n try {\n // Set env vars from CLI flags (CLI takes precedence over existing env vars)\n if (tokenPath) {\n process.env.GOOGLE_WORKSPACE_MCP_TOKEN_PATH = tokenPath;\n }\n if (credentialsPath) {\n process.env.GOOGLE_DRIVE_OAUTH_CREDENTIALS = credentialsPath;\n }\n\n // Initialize OAuth client\n const oauth2Client = await initializeOAuth2Client();\n\n // Create and start auth server\n const authServer = new AuthServer(oauth2Client);\n await authServer.start();\n\n // Wait for completion\n const checkInterval = setInterval(() => {\n if (authServer.authCompletedSuccessfully) {\n clearInterval(checkInterval);\n process.exit(0);\n }\n }, 1000);\n } catch (error) {\n console.error(\"Authentication failed:\", error);\n process.exit(1);\n }\n}\n\n// -----------------------------------------------------------------------------\n// MAIN EXECUTION\n// -----------------------------------------------------------------------------\n\ninterface CliArgs {\n command: string | undefined;\n tokenPath?: string;\n credentialsPath?: string;\n}\n\nfunction parseCliArgs(): CliArgs {\n const args = process.argv.slice(2);\n let command: string | undefined;\n let tokenPath: string | undefined;\n let credentialsPath: string | undefined;\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n\n // Handle --token-path flag\n if (arg === \"--token-path\" && i + 1 < args.length) {\n tokenPath = args[++i];\n continue;\n }\n\n // Handle --credentials-path flag\n if (arg === \"--credentials-path\" && i + 1 < args.length) {\n credentialsPath = args[++i];\n continue;\n }\n\n // Handle special version/help flags as commands\n if (arg === \"--version\" || arg === \"-v\" || arg === \"--help\" || arg === \"-h\") {\n command = arg;\n continue;\n }\n\n // Check for command (first non-option argument)\n if (!command && !arg.startsWith(\"--\")) {\n command = arg;\n continue;\n }\n }\n\n return { command, tokenPath, credentialsPath };\n}\n\nasync function main() {\n const { command, tokenPath, credentialsPath } = parseCliArgs();\n\n switch (command) {\n case \"auth\":\n await runAuthServer(tokenPath, credentialsPath);\n break;\n case \"start\":\n case undefined:\n try {\n // Start the MCP server\n log(\"Starting Google Workspace MCP server...\");\n const transport = new StdioServerTransport();\n await server.connect(transport);\n log(\"Server started successfully\");\n\n // Set up graceful shutdown\n process.on(\"SIGINT\", async () => {\n await server.close();\n process.exit(0);\n });\n process.on(\"SIGTERM\", async () => {\n await server.close();\n process.exit(0);\n });\n } catch (error) {\n console.error(\"Failed to start server:\", error);\n process.exit(1);\n }\n break;\n case \"version\":\n case \"--version\":\n case \"-v\":\n showVersion();\n break;\n case \"help\":\n case \"--help\":\n case \"-h\":\n showHelp();\n break;\n default:\n console.error(`Unknown command: ${command}`);\n showHelp();\n process.exit(1);\n }\n}\n\n// Export server and main for testing or potential programmatic use\nexport { main, server };\n\n// Run the CLI\nmain().catch((error) => {\n console.error(\"Fatal error:\", error);\n process.exit(1);\n});\n", "import { OAuth2Client } from \"google-auth-library\";\nimport * as fs from \"fs/promises\";\nimport { getKeysFilePath, generateCredentialsErrorMessage, OAuthCredentials } from \"./utils.js\";\n\nasync function loadCredentialsFromFile(): Promise<OAuthCredentials> {\n const keysContent = await fs.readFile(getKeysFilePath(), \"utf-8\");\n const keys = JSON.parse(keysContent);\n\n if (keys.installed) {\n // Standard OAuth credentials file format\n const { client_id, client_secret, redirect_uris } = keys.installed;\n return { client_id, client_secret, redirect_uris };\n } else if (keys.web) {\n // Web application credentials format\n const { client_id, client_secret, redirect_uris } = keys.web;\n return { client_id, client_secret, redirect_uris };\n } else if (keys.client_id) {\n // Direct format (simplified)\n return {\n client_id: keys.client_id,\n client_secret: keys.client_secret,\n redirect_uris: keys.redirect_uris || [\"http://localhost:3000/oauth2callback\"],\n };\n } else {\n throw new Error(\n 'Invalid credentials file format. Expected either \"installed\", \"web\" object or direct client_id field.',\n );\n }\n}\n\nasync function loadCredentialsWithFallback(): Promise<OAuthCredentials> {\n try {\n return await loadCredentialsFromFile();\n } catch (fileError) {\n // Check for legacy client_secret.json\n const legacyPath = process.env.GOOGLE_CLIENT_SECRET_PATH || \"client_secret.json\";\n try {\n const legacyContent = await fs.readFile(legacyPath, \"utf-8\");\n const legacyKeys = JSON.parse(legacyContent);\n console.error(\n \"Warning: Using legacy client_secret.json. Please migrate to gcp-oauth.keys.json\",\n );\n\n if (legacyKeys.installed) {\n return legacyKeys.installed;\n } else if (legacyKeys.web) {\n return legacyKeys.web;\n } else {\n throw new Error(\"Invalid legacy credentials format\");\n }\n } catch {\n // Generate helpful error message\n const errorMessage = generateCredentialsErrorMessage();\n throw new Error(\n `${errorMessage}\\n\\nOriginal error: ${fileError instanceof Error ? fileError.message : fileError}`,\n );\n }\n }\n}\n\nexport async function initializeOAuth2Client(): Promise<OAuth2Client> {\n try {\n const credentials = await loadCredentialsWithFallback();\n\n // Use the first redirect URI as the default for the base client\n return new OAuth2Client({\n clientId: credentials.client_id,\n clientSecret: credentials.client_secret || undefined,\n redirectUri: credentials.redirect_uris?.[0] || \"http://localhost:3000/oauth2callback\",\n });\n } catch (error) {\n throw new Error(`Error loading OAuth keys: ${error instanceof Error ? error.message : error}`);\n }\n}\n\nexport async function loadCredentials(): Promise<{\n client_id: string;\n client_secret?: string;\n}> {\n try {\n const credentials = await loadCredentialsWithFallback();\n\n if (!credentials.client_id) {\n throw new Error(\"Client ID missing in credentials.\");\n }\n return {\n client_id: credentials.client_id,\n client_secret: credentials.client_secret,\n };\n } catch (error) {\n throw new Error(`Error loading credentials: ${error instanceof Error ? error.message : error}`);\n }\n}\n", "import * as path from \"path\";\nimport * as os from \"os\";\nimport { fileURLToPath } from \"url\";\n\n// Helper to get the project root directory reliably\nfunction getProjectRoot(): string {\n const __dirname = path.dirname(fileURLToPath(import.meta.url));\n // In build output (e.g., dist/auth/utils.js), __dirname is .../dist/auth\n // Go up TWO levels to get the project root\n const projectRoot = path.join(__dirname, \"..\", \"..\");\n return path.resolve(projectRoot);\n}\n\n// Returns the absolute path for the saved token file.\n// Uses XDG Base Directory spec with fallback to home directory\nexport function getSecureTokenPath(): string {\n // Check for custom token path environment variable first (new name)\n const customTokenPath = process.env.GOOGLE_WORKSPACE_MCP_TOKEN_PATH;\n if (customTokenPath) {\n return path.resolve(customTokenPath);\n }\n\n // Legacy environment variable support\n const legacyTokenPath = process.env.GOOGLE_DRIVE_MCP_TOKEN_PATH;\n if (legacyTokenPath) {\n return path.resolve(legacyTokenPath);\n }\n\n // Use XDG Base Directory spec or fallback to ~/.config\n const configHome = process.env.XDG_CONFIG_HOME || path.join(os.homedir(), \".config\");\n\n const tokenDir = path.join(configHome, \"google-workspace-mcp\");\n return path.join(tokenDir, \"tokens.json\");\n}\n\n// Returns the legacy token path for backward compatibility\nexport function getLegacyTokenPath(): string {\n const projectRoot = getProjectRoot();\n return path.join(projectRoot, \".gcp-saved-tokens.json\");\n}\n\n// Additional legacy paths to check\nexport function getAdditionalLegacyPaths(): string[] {\n return [\n process.env.GOOGLE_TOKEN_PATH,\n path.join(process.cwd(), \"google-tokens.json\"),\n path.join(process.cwd(), \".gcp-saved-tokens.json\"),\n ].filter(Boolean) as string[];\n}\n\n// Returns the absolute path for the GCP OAuth keys file with priority:\n// 1. Environment variable GOOGLE_DRIVE_OAUTH_CREDENTIALS (highest priority)\n// 2. Default file path (lowest priority)\nexport function getKeysFilePath(): string {\n // Priority 1: Environment variable\n const envCredentialsPath = process.env.GOOGLE_DRIVE_OAUTH_CREDENTIALS;\n if (envCredentialsPath) {\n return path.resolve(envCredentialsPath);\n }\n\n // Priority 2: Default file path\n const projectRoot = getProjectRoot();\n const keysPath = path.join(projectRoot, \"gcp-oauth.keys.json\");\n return keysPath;\n}\n\n// Interface for OAuth credentials\nexport interface OAuthCredentials {\n client_id: string;\n client_secret?: string;\n redirect_uris?: string[];\n}\n\n// Generate helpful error message for missing credentials\nexport function generateCredentialsErrorMessage(): string {\n return `\nOAuth credentials not found. Please provide credentials using one of these methods:\n\n1. Environment variable:\n Set GOOGLE_DRIVE_OAUTH_CREDENTIALS to the path of your credentials file:\n export GOOGLE_DRIVE_OAUTH_CREDENTIALS=\"/path/to/gcp-oauth.keys.json\"\n\n2. Default file path:\n Place your gcp-oauth.keys.json file in the package root directory.\n\nToken storage:\n- Tokens are saved to: ${getSecureTokenPath()}\n- To use a custom token location, set GOOGLE_WORKSPACE_MCP_TOKEN_PATH environment variable\n\nTo get OAuth credentials:\n1. Go to the Google Cloud Console (https://console.cloud.google.com/)\n2. Create or select a project\n3. Enable the Google Drive, Docs, Sheets, and Slides APIs\n4. Create OAuth 2.0 credentials (Desktop app type)\n5. Download the credentials file as gcp-oauth.keys.json\n`.trim();\n}\n", "import { OAuth2Client } from \"google-auth-library\";\nimport { TokenManager } from \"./tokenManager.js\";\nimport http from \"http\";\nimport os from \"os\";\nimport path from \"path\";\nimport { URL } from \"url\";\nimport open from \"open\";\nimport { loadCredentials } from \"./client.js\";\nimport { log } from \"../utils/logging.js\";\n\n// OAuth scopes for Google Drive, Docs, Sheets, Slides, Calendar, and Gmail\nconst SCOPES = [\n \"https://www.googleapis.com/auth/drive\",\n \"https://www.googleapis.com/auth/drive.file\",\n \"https://www.googleapis.com/auth/drive.readonly\",\n \"https://www.googleapis.com/auth/documents\",\n \"https://www.googleapis.com/auth/spreadsheets\",\n \"https://www.googleapis.com/auth/presentations\",\n \"https://www.googleapis.com/auth/calendar\",\n \"https://www.googleapis.com/auth/gmail.modify\",\n \"https://mail.google.com/\", // Required for message deletion\n \"https://www.googleapis.com/auth/gmail.settings.basic\",\n];\n\nexport class AuthServer {\n private baseOAuth2Client: OAuth2Client; // Used by TokenManager for validation/refresh\n private flowOAuth2Client: OAuth2Client | null = null; // Used specifically for the auth code flow\n private server: http.Server | null = null;\n private tokenManager: TokenManager;\n private portRange: { start: number; end: number };\n public authCompletedSuccessfully = false; // Flag for standalone script\n\n constructor(oauth2Client: OAuth2Client) {\n this.baseOAuth2Client = oauth2Client;\n this.tokenManager = new TokenManager(oauth2Client);\n this.portRange = { start: 3000, end: 3004 };\n }\n\n private createServer(): http.Server {\n return http.createServer(async (req, res) => {\n const url = new URL(req.url || \"/\", `http://localhost`);\n\n if (url.pathname === \"/\") {\n // Handle root - show auth link\n const clientForUrl = this.flowOAuth2Client || this.baseOAuth2Client;\n const authUrl = clientForUrl.generateAuthUrl({\n access_type: \"offline\",\n scope: SCOPES,\n prompt: \"consent\",\n });\n res.writeHead(200, { \"Content-Type\": \"text/html\" });\n res.end(\n `<h1>Google Drive Authentication</h1><a href=\"${authUrl}\">Authenticate with Google</a>`,\n );\n } else if (url.pathname === \"/oauth2callback\") {\n // Handle OAuth callback\n const code = url.searchParams.get(\"code\");\n if (!code) {\n res.writeHead(400, { \"Content-Type\": \"text/plain\" });\n res.end(\"Authorization code missing\");\n return;\n }\n // IMPORTANT: Use the flowOAuth2Client to exchange the code\n if (!this.flowOAuth2Client) {\n res.writeHead(500, { \"Content-Type\": \"text/plain\" });\n res.end(\"Authentication flow not properly initiated.\");\n return;\n }\n try {\n const { tokens } = await this.flowOAuth2Client.getToken(code);\n // Save tokens using the TokenManager (which uses the base client)\n await this.tokenManager.saveTokens(tokens);\n this.authCompletedSuccessfully = true;\n\n // Get the path where tokens were saved\n const tokenPath = this.tokenManager.getTokenPath();\n\n // Detect if tokens are stored in a project directory (not ~/.config)\n const homeConfig = path.join(os.homedir(), \".config\");\n const isProjectLevel = !tokenPath.startsWith(homeConfig);\n const credentialsDir = path.basename(path.dirname(tokenPath));\n const gitignoreWarning = isProjectLevel\n ? `\n <div class=\"warning\">\n <p><strong>\u26A0\uFE0F Security:</strong> Add your credentials directory to .gitignore:</p>\n <p><code>${credentialsDir}/</code></p>\n </div>`\n : \"\";\n\n // Send a more informative HTML response including the path\n res.writeHead(200, { \"Content-Type\": \"text/html\" });\n res.end(`\n <!DOCTYPE html>\n <html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Authentication Successful</title>\n <style>\n body { font-family: sans-serif; display: flex; justify-content: center; align-items: center; height: 100vh; background-color: #f4f4f4; margin: 0; }\n .container { text-align: center; padding: 2em; background-color: #fff; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); max-width: 500px; }\n h1 { color: #4CAF50; }\n p { color: #333; margin-bottom: 0.5em; }\n code { background-color: #eee; padding: 0.2em 0.4em; border-radius: 3px; font-size: 0.9em; }\n .warning { background-color: #fff3cd; border: 1px solid #ffc107; border-radius: 4px; padding: 1em; margin-top: 1em; }\n .warning p { color: #856404; margin: 0.3em 0; }\n </style>\n </head>\n <body>\n <div class=\"container\">\n <h1>Authentication Successful!</h1>\n <p>Your authentication tokens have been saved successfully to:</p>\n <p><code>${tokenPath}</code></p>${gitignoreWarning}\n <p style=\"margin-top: 1em;\">You can now close this browser window.</p>\n </div>\n </body>\n </html>\n `);\n } catch (error: unknown) {\n this.authCompletedSuccessfully = false;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n // Send an HTML error response\n res.writeHead(500, { \"Content-Type\": \"text/html\" });\n res.end(`\n <!DOCTYPE html>\n <html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Authentication Failed</title>\n <style>\n body { font-family: sans-serif; display: flex; justify-content: center; align-items: center; height: 100vh; background-color: #f4f4f4; margin: 0; }\n .container { text-align: center; padding: 2em; background-color: #fff; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }\n h1 { color: #F44336; }\n p { color: #333; }\n </style>\n </head>\n <body>\n <div class=\"container\">\n <h1>Authentication Failed</h1>\n <p>An error occurred during authentication:</p>\n <p><code>${message}</code></p>\n <p>Please try again or check the server logs.</p>\n </div>\n </body>\n </html>\n `);\n }\n } else {\n res.writeHead(404, { \"Content-Type\": \"text/plain\" });\n res.end(\"Not Found\");\n }\n });\n }\n\n async start(openBrowser = true): Promise<boolean> {\n if (await this.tokenManager.validateTokens()) {\n this.authCompletedSuccessfully = true;\n return true;\n }\n\n // Try to start the server and get the port\n const port = await this.startServerOnAvailablePort();\n if (port === null) {\n this.authCompletedSuccessfully = false;\n return false;\n }\n\n // Successfully started server on `port`. Now create the flow-specific OAuth client.\n try {\n const { client_id, client_secret } = await loadCredentials();\n this.flowOAuth2Client = new OAuth2Client(\n client_id,\n client_secret || undefined,\n `http://localhost:${port}/oauth2callback`,\n );\n } catch (error) {\n // Could not load credentials, cannot proceed with auth flow\n log(\"Failed to load credentials for auth flow:\", error);\n this.authCompletedSuccessfully = false;\n await this.stop(); // Stop the server we just started\n return false;\n }\n\n if (openBrowser) {\n // Generate Auth URL using the newly created flow client\n const authorizeUrl = this.flowOAuth2Client.generateAuthUrl({\n access_type: \"offline\",\n scope: SCOPES,\n prompt: \"consent\",\n });\n\n console.error(\"\\n\uD83D\uDD10 AUTHENTICATION REQUIRED\");\n console.error(\"\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\");\n console.error(\"\\nOpening your browser to authenticate...\");\n console.error(`If the browser doesn't open, visit:\\n${authorizeUrl}\\n`);\n\n await open(authorizeUrl);\n }\n\n return true; // Auth flow initiated\n }\n\n private async startServerOnAvailablePort(): Promise<number | null> {\n for (let port = this.portRange.start; port <= this.portRange.end; port++) {\n try {\n await new Promise<void>((resolve, reject) => {\n // Create a new server instance for this port attempt\n const testServer = this.createServer();\n testServer.listen(port, () => {\n this.server = testServer; // Assign to class property *only* if successful\n console.error(`Authentication server listening on http://localhost:${port}`);\n resolve();\n });\n testServer.on(\"error\", (err: NodeJS.ErrnoException) => {\n if (err.code === \"EADDRINUSE\") {\n // Port is in use, close the test server and reject\n testServer.close(() => reject(err));\n } else {\n // Other error, reject\n reject(err);\n }\n });\n });\n return port; // Port successfully bound\n } catch (error: unknown) {\n // Check if it's EADDRINUSE, otherwise rethrow or handle\n const nodeErr = error as NodeJS.ErrnoException;\n if (nodeErr.code !== \"EADDRINUSE\") {\n // An unexpected error occurred during server start\n log(\"Failed to start auth server:\", error);\n return null;\n }\n // EADDRINUSE occurred, loop continues\n }\n }\n console.error(\n \"No available ports for authentication server (tried ports\",\n this.portRange.start,\n \"-\",\n this.portRange.end,\n \")\",\n );\n return null; // No port found\n }\n\n public getRunningPort(): number | null {\n if (this.server) {\n const address = this.server.address();\n if (typeof address === \"object\" && address !== null) {\n return address.port;\n }\n }\n return null;\n }\n\n async stop(): Promise<void> {\n return new Promise((resolve, reject) => {\n if (this.server) {\n this.server.close((err) => {\n if (err) {\n reject(err);\n } else {\n this.server = null;\n resolve();\n }\n });\n } else {\n resolve();\n }\n });\n }\n}\n", "import { OAuth2Client, Credentials } from \"google-auth-library\";\nimport * as fs from \"fs/promises\";\nimport * as path from \"path\";\nimport { getSecureTokenPath, getLegacyTokenPath, getAdditionalLegacyPaths } from \"./utils.js\";\nimport { GaxiosError } from \"gaxios\";\nimport { log } from \"../utils/logging.js\";\n\n/** Type guard for NodeJS errors with a `code` property (e.g., ENOENT, EEXIST) */\nfunction isNodeError(error: unknown): error is NodeJS.ErrnoException {\n return error instanceof Error && \"code\" in error;\n}\n\nexport class TokenManager {\n private oauth2Client: OAuth2Client;\n private tokenPath: string;\n\n constructor(oauth2Client: OAuth2Client) {\n this.oauth2Client = oauth2Client;\n this.tokenPath = getSecureTokenPath();\n this.setupTokenRefresh();\n }\n\n // Method to expose the token path\n public getTokenPath(): string {\n return this.tokenPath;\n }\n\n private async ensureTokenDirectoryExists(): Promise<void> {\n try {\n const dir = path.dirname(this.tokenPath);\n await fs.mkdir(dir, { recursive: true });\n } catch (error: unknown) {\n // Ignore errors if directory already exists, re-throw others\n if (isNodeError(error) && error.code !== \"EEXIST\") {\n log(\"Failed to create token directory:\", error);\n throw error;\n }\n }\n }\n\n private setupTokenRefresh(): void {\n this.oauth2Client.on(\"tokens\", async (newTokens) => {\n try {\n await this.ensureTokenDirectoryExists();\n const currentTokens = JSON.parse(await fs.readFile(this.tokenPath, \"utf-8\"));\n const updatedTokens = {\n ...currentTokens,\n ...newTokens,\n refresh_token: newTokens.refresh_token || currentTokens.refresh_token,\n };\n await fs.writeFile(this.tokenPath, JSON.stringify(updatedTokens, null, 2), {\n mode: 0o600,\n });\n log(\"Tokens updated and saved\");\n } catch (error: unknown) {\n // Handle case where currentTokens might not exist yet\n if (isNodeError(error) && error.code === \"ENOENT\") {\n try {\n await fs.writeFile(this.tokenPath, JSON.stringify(newTokens, null, 2), { mode: 0o600 });\n log(\"New tokens saved\");\n } catch (writeError) {\n log(\"Error saving initial tokens:\", writeError);\n }\n } else {\n log(\"Error saving updated tokens:\", error);\n }\n }\n });\n }\n\n private async migrateLegacyTokens(): Promise<boolean> {\n // Check all possible legacy locations\n const legacyPaths = [getLegacyTokenPath(), ...getAdditionalLegacyPaths()];\n\n for (const legacyPath of legacyPaths) {\n try {\n // Check if legacy tokens exist\n if (\n !(await fs\n .access(legacyPath)\n .then(() => true)\n .catch(() => false))\n ) {\n continue; // Try next location\n }\n\n // Read legacy tokens\n const legacyTokens = JSON.parse(await fs.readFile(legacyPath, \"utf-8\"));\n\n if (!legacyTokens || typeof legacyTokens !== \"object\") {\n log(`Invalid legacy token format at ${legacyPath}, skipping`);\n continue;\n }\n\n // Ensure new token directory exists\n await this.ensureTokenDirectoryExists();\n\n // Copy to new location\n await fs.writeFile(this.tokenPath, JSON.stringify(legacyTokens, null, 2), {\n mode: 0o600,\n });\n\n log(`Migrated tokens from legacy location: ${legacyPath} to: ${this.tokenPath}`);\n\n // Optionally remove legacy file after successful migration\n try {\n await fs.unlink(legacyPath);\n log(\"Removed legacy token file\");\n } catch (unlinkErr) {\n log(\"Warning: Could not remove legacy token file:\", unlinkErr);\n }\n\n return true;\n } catch (error) {\n log(`Error migrating legacy tokens from ${legacyPath}`, error);\n // Continue to next location\n }\n }\n\n return false; // No legacy tokens found or migrated\n }\n\n async loadSavedTokens(): Promise<boolean> {\n try {\n await this.ensureTokenDirectoryExists();\n\n // Check if current token file exists\n const tokenExists = await fs\n .access(this.tokenPath)\n .then(() => true)\n .catch(() => false);\n\n // If no current tokens, try to migrate from legacy location\n if (!tokenExists) {\n const migrated = await this.migrateLegacyTokens();\n if (!migrated) {\n log(\"No token file found at:\", this.tokenPath);\n return false;\n }\n }\n\n const tokens = JSON.parse(await fs.readFile(this.tokenPath, \"utf-8\"));\n\n if (!tokens || typeof tokens !== \"object\") {\n log(\"Invalid token format in file:\", this.tokenPath);\n return false;\n }\n\n this.oauth2Client.setCredentials(tokens);\n log(\"Tokens loaded successfully\");\n return true;\n } catch (error: unknown) {\n log(\"Error loading tokens:\", error);\n // Attempt to delete potentially corrupted token file\n if (isNodeError(error) && error.code !== \"ENOENT\") {\n try {\n await fs.unlink(this.tokenPath);\n log(\"Removed potentially corrupted token file\");\n } catch {\n /* ignore */\n }\n }\n return false;\n }\n }\n\n async refreshTokensIfNeeded(): Promise<boolean> {\n const expiryDate = this.oauth2Client.credentials.expiry_date;\n const isExpired = expiryDate\n ? Date.now() >= expiryDate - 5 * 60 * 1000 // 5 minute buffer\n : !this.oauth2Client.credentials.access_token; // No token means we need one\n\n if (isExpired && this.oauth2Client.credentials.refresh_token) {\n log(\"Auth token expired or nearing expiry, refreshing...\");\n try {\n const response = await this.oauth2Client.refreshAccessToken();\n const newTokens = response.credentials;\n\n if (!newTokens.access_token) {\n throw new Error(\"Received invalid tokens during refresh\");\n }\n // The 'tokens' event listener should handle saving\n this.oauth2Client.setCredentials(newTokens);\n log(\"Token refreshed successfully\");\n return true;\n } catch (refreshError) {\n if (\n refreshError instanceof GaxiosError &&\n refreshError.response?.data?.error === \"invalid_grant\"\n ) {\n log(\n \"Error refreshing auth token: Invalid grant. Token likely expired or revoked. Please re-authenticate.\",\n );\n // Optionally clear the potentially invalid tokens here\n await this.clearTokens();\n return false; // Indicate failure due to invalid grant\n } else {\n // Handle other refresh errors\n log(\"Error refreshing auth token:\", refreshError);\n return false;\n }\n }\n } else if (\n !this.oauth2Client.credentials.access_token &&\n !this.oauth2Client.credentials.refresh_token\n ) {\n log(\"No access or refresh token available. Please re-authenticate.\");\n return false;\n } else {\n // Token is valid or no refresh token available\n return true;\n }\n }\n\n async validateTokens(): Promise<boolean> {\n if (!this.oauth2Client.credentials || !this.oauth2Client.credentials.access_token) {\n // Try loading first if no credentials set\n if (!(await this.loadSavedTokens())) {\n return false; // No saved tokens to load\n }\n // Check again after loading\n if (!this.oauth2Client.credentials || !this.oauth2Client.credentials.access_token) {\n return false; // Still no token after loading\n }\n }\n return this.refreshTokensIfNeeded();\n }\n\n async saveTokens(tokens: Credentials): Promise<void> {\n try {\n await this.ensureTokenDirectoryExists();\n await fs.writeFile(this.tokenPath, JSON.stringify(tokens, null, 2), {\n mode: 0o600,\n });\n this.oauth2Client.setCredentials(tokens);\n log(\"Tokens saved successfully to:\", this.tokenPath);\n } catch (error: unknown) {\n log(\"Error saving tokens:\", error);\n throw error;\n }\n }\n\n async clearTokens(): Promise<void> {\n try {\n this.oauth2Client.setCredentials({}); // Clear in memory\n await fs.unlink(this.tokenPath);\n log(\"Tokens cleared successfully\");\n } catch (error: unknown) {\n if (isNodeError(error) && error.code === \"ENOENT\") {\n // File already gone, which is fine\n log(\"Token file already deleted\");\n } else {\n log(\"Error clearing tokens:\", error);\n // Don't re-throw, clearing is best-effort\n }\n }\n }\n}\n", "// Main authentication module that re-exports and orchestrates the modular components\nimport type { OAuth2Client } from \"google-auth-library\";\nimport { initializeOAuth2Client } from \"./auth/client.js\";\nimport { AuthServer } from \"./auth/server.js\";\nimport { TokenManager } from \"./auth/tokenManager.js\";\nimport { log } from \"./utils/logging.js\";\n\nexport { TokenManager } from \"./auth/tokenManager.js\";\nexport { initializeOAuth2Client } from \"./auth/client.js\";\nexport { AuthServer } from \"./auth/server.js\";\n\n/**\n * Authenticate and return OAuth2 client\n * This is the main entry point for authentication in the MCP server\n */\nexport async function authenticate(): Promise<OAuth2Client> {\n log(\"Initializing authentication...\");\n\n // Initialize OAuth2 client\n const oauth2Client = await initializeOAuth2Client();\n const tokenManager = new TokenManager(oauth2Client);\n\n // Try to validate existing tokens\n if (await tokenManager.validateTokens()) {\n log(\"Authentication successful - using existing tokens\");\n return oauth2Client;\n }\n\n // No valid tokens, need to authenticate\n log(\"No valid authentication tokens found. Starting authentication flow...\");\n\n const authServer = new AuthServer(oauth2Client);\n const authSuccess = await authServer.start(true);\n\n if (!authSuccess) {\n throw new Error(\"Authentication failed. Please check your credentials and try again.\");\n }\n\n // Wait for authentication to complete\n await new Promise<void>((resolve) => {\n const checkInterval = setInterval(async () => {\n if (authServer.authCompletedSuccessfully) {\n clearInterval(checkInterval);\n await authServer.stop();\n resolve();\n }\n }, 1000);\n });\n\n return oauth2Client;\n}\n", "/**\n * Service configuration for enabling/disabling Google Workspace services.\n *\n * Users can set GOOGLE_WORKSPACE_SERVICES env var to a comma-separated list\n * of services to enable (e.g., \"drive,gmail\"). If not set, all services are enabled.\n */\n\nexport const SERVICE_NAMES = [\"drive\", \"docs\", \"sheets\", \"slides\", \"calendar\", \"gmail\"] as const;\nexport type ServiceName = (typeof SERVICE_NAMES)[number];\n\n/** Unified tools require all these services to function */\nconst UNIFIED_REQUIRED_SERVICES: ServiceName[] = [\"drive\", \"docs\", \"sheets\", \"slides\"];\n\n/** Cached set of enabled services (null = not yet parsed) */\nlet enabledServices: Set<ServiceName> | null = null;\n\n/**\n * Parse and return the set of enabled services from GOOGLE_WORKSPACE_SERVICES env var.\n *\n * - Not set \u2192 all services enabled (backward compatible)\n * - Empty \u2192 no services enabled\n * - \"drive,gmail\" \u2192 only those services enabled\n * - Unknown services \u2192 warning logged, valid services still work\n */\nexport function getEnabledServices(): Set<ServiceName> {\n if (enabledServices !== null) return enabledServices;\n\n const envValue = process.env.GOOGLE_WORKSPACE_SERVICES;\n\n // Not set = all enabled (backward compatible)\n if (envValue === undefined) {\n enabledServices = new Set(SERVICE_NAMES);\n return enabledServices;\n }\n\n // Empty = none enabled\n if (envValue.trim() === \"\") {\n enabledServices = new Set();\n return enabledServices;\n }\n\n // Parse comma-separated list\n const requested = envValue\n .split(\",\")\n .map((s) => s.trim().toLowerCase())\n .filter(Boolean);\n const valid = new Set<ServiceName>();\n const unknown: string[] = [];\n\n for (const service of requested) {\n if (SERVICE_NAMES.includes(service as ServiceName)) {\n valid.add(service as ServiceName);\n } else {\n unknown.push(service);\n }\n }\n\n if (unknown.length > 0) {\n console.warn(\n `[google-workspace-mcp] Unknown services: ${unknown.join(\", \")}. ` +\n `Valid: ${SERVICE_NAMES.join(\", \")}`,\n );\n }\n\n enabledServices = valid;\n return enabledServices;\n}\n\n/**\n * Check if a specific service is enabled.\n */\nexport function isServiceEnabled(service: ServiceName): boolean {\n return getEnabledServices().has(service);\n}\n\n/**\n * Check if unified tools (create_file, update_file, get_file_content) are enabled.\n * Unified tools require drive, docs, sheets, and slides to all be enabled.\n */\nexport function areUnifiedToolsEnabled(): boolean {\n const enabled = getEnabledServices();\n return UNIFIED_REQUIRED_SERVICES.every((s) => enabled.has(s));\n}\n\n/**\n * Reset cached service config (for testing).\n */\nexport function resetServiceConfig(): void {\n enabledServices = null;\n}\n", "/**\n * Tool definitions for the Google Drive MCP server.\n * Each tool definition includes name, description, inputSchema, and optionally outputSchema.\n */\n\n// JSON Schema conditional keywords for machine-parseable requirements\ninterface JsonSchemaConditional {\n if?: { properties: Record<string, unknown> };\n then?: { required: string[] };\n}\n\nexport interface ToolDefinition {\n name: string;\n description: string;\n inputSchema: {\n type: \"object\";\n properties: Record<string, unknown>;\n required?: string[];\n // JSON Schema conditional keywords for action-based requirements\n if?: { properties: Record<string, unknown> };\n then?: { required: string[] };\n allOf?: JsonSchemaConditional[];\n };\n outputSchema?: {\n type: \"object\";\n properties: Record<string, unknown>;\n };\n}\n\n// Drive tools\nexport const driveTools: ToolDefinition[] = [\n {\n name: \"search\",\n description: \"Search files and folders in Drive (max 100 results per page)\",\n inputSchema: {\n type: \"object\",\n properties: {\n query: { type: \"string\", description: \"Search query\" },\n searchType: {\n type: \"string\",\n enum: [\"fulltext\", \"name\", \"name_exact\"],\n description:\n \"Search type: 'fulltext' (default, searches file content), 'name' (filename contains query), 'name_exact' (exact filename match)\",\n },\n pageSize: {\n type: \"number\",\n description: \"(optional, default: 50) Results per page (max 100)\",\n },\n pageToken: {\n type: \"string\",\n description: \"(optional) Token for next page of results\",\n },\n },\n required: [\"query\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n files: {\n type: \"array\",\n description: \"List of matching files\",\n items: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"File ID\" },\n name: { type: \"string\", description: \"File name\" },\n mimeType: { type: \"string\", description: \"MIME type\" },\n modifiedTime: {\n type: \"string\",\n description: \"Last modified timestamp\",\n },\n size: { type: \"string\", description: \"File size in bytes\" },\n },\n },\n },\n nextPageToken: {\n type: \"string\",\n description: \"Token for fetching next page, if more results exist\",\n },\n },\n },\n },\n {\n name: \"create_text_file\",\n description: \"Create a text or markdown file\",\n inputSchema: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"File name (.txt or .md)\" },\n content: { type: \"string\", description: \"File content\" },\n parentFolderId: {\n type: \"string\",\n description: \"Parent folder ID (mutually exclusive with parentPath)\",\n },\n parentPath: {\n type: \"string\",\n description:\n \"Parent folder path like '/Documents/Projects' (creates folders if needed, mutually exclusive with parentFolderId)\",\n },\n },\n required: [\"name\", \"content\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Created file ID\" },\n name: { type: \"string\", description: \"Created file name\" },\n },\n },\n },\n {\n name: \"update_text_file\",\n description: \"Update content of a text or markdown file in Google Drive\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"ID of the file to update\" },\n content: { type: \"string\", description: \"New file content\" },\n name: {\n type: \"string\",\n description: \"Optional new name (.txt or .md)\",\n },\n },\n required: [\"fileId\", \"content\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"Updated file name\" },\n modifiedTime: {\n type: \"string\",\n description: \"Last modified timestamp (ISO 8601)\",\n },\n },\n },\n },\n {\n name: \"create_folder\",\n description: \"Create a new folder in Google Drive\",\n inputSchema: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"Folder name\" },\n parent: {\n type: \"string\",\n description: \"Parent folder ID (mutually exclusive with parentPath)\",\n },\n parentPath: {\n type: \"string\",\n description:\n \"Parent folder path like '/Documents/Projects' (creates folders if needed, mutually exclusive with parent)\",\n },\n },\n required: [\"name\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Created folder ID\" },\n name: { type: \"string\", description: \"Created folder name\" },\n },\n },\n },\n {\n name: \"list_folder\",\n description: \"List folder contents (max 100 items per page)\",\n inputSchema: {\n type: \"object\",\n properties: {\n folderId: { type: \"string\", description: \"(optional) Folder ID (defaults to root)\" },\n pageSize: {\n type: \"number\",\n description: \"(optional, default: 50) Items to return (max 100)\",\n },\n pageToken: { type: \"string\", description: \"(optional) Token for next page\" },\n },\n },\n outputSchema: {\n type: \"object\",\n properties: {\n items: {\n type: \"array\",\n description: \"List of files and folders\",\n items: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Item ID\" },\n name: { type: \"string\", description: \"Item name\" },\n mimeType: { type: \"string\", description: \"MIME type\" },\n modifiedTime: {\n type: \"string\",\n description: \"Last modified timestamp\",\n },\n size: {\n type: \"string\",\n description: \"File size in bytes (folders have no size)\",\n },\n },\n },\n },\n nextPageToken: {\n type: \"string\",\n description: \"Token for fetching next page, if more items exist\",\n },\n },\n },\n },\n {\n name: \"delete_item\",\n description: \"Move items to trash\",\n inputSchema: {\n type: \"object\",\n properties: {\n itemId: { type: \"string\", description: \"ID of the item to delete\" },\n },\n required: [\"itemId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\", description: \"Whether the deletion succeeded\" },\n itemId: { type: \"string\", description: \"ID of the deleted item\" },\n },\n },\n },\n {\n name: \"rename_item\",\n description: \"Rename a file or folder\",\n inputSchema: {\n type: \"object\",\n properties: {\n itemId: { type: \"string\", description: \"ID of the item to rename\" },\n newName: { type: \"string\", description: \"New name\" },\n },\n required: [\"itemId\", \"newName\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\", description: \"Whether the rename succeeded\" },\n id: { type: \"string\", description: \"Item ID\" },\n name: { type: \"string\", description: \"New name\" },\n },\n },\n },\n {\n name: \"move_item\",\n description: \"Move items to a new folder\",\n inputSchema: {\n type: \"object\",\n properties: {\n itemId: { type: \"string\", description: \"ID of the item to move\" },\n destinationFolderId: {\n type: \"string\",\n description: \"Destination folder ID (mutually exclusive with destinationPath)\",\n },\n destinationPath: {\n type: \"string\",\n description:\n \"Destination folder path like '/Archive/2024' (creates folders if needed, mutually exclusive with destinationFolderId)\",\n },\n },\n required: [\"itemId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n itemName: { type: \"string\", description: \"Name of the moved item\" },\n destinationName: {\n type: \"string\",\n description: \"Destination folder name\",\n },\n },\n },\n },\n {\n name: \"copy_file\",\n description: \"Copy a file with optional new name\",\n inputSchema: {\n type: \"object\",\n properties: {\n sourceFileId: { type: \"string\", description: \"ID of the file to copy\" },\n destinationName: {\n type: \"string\",\n description: \"Name for the copied file (defaults to 'Copy of <original>')\",\n },\n destinationFolderId: {\n type: \"string\",\n description: \"Destination folder ID (defaults to same folder as source)\",\n },\n },\n required: [\"sourceFileId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"New file ID\" },\n name: { type: \"string\", description: \"New file name\" },\n webViewLink: {\n type: \"string\",\n description: \"Link to view the new file\",\n },\n },\n },\n },\n {\n name: \"get_file_metadata\",\n description: \"Get file or folder metadata\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"ID of the file or folder\" },\n },\n required: [\"fileId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"File ID\" },\n name: { type: \"string\", description: \"File name\" },\n mimeType: { type: \"string\", description: \"MIME type\" },\n size: { type: \"string\", description: \"File size in bytes\" },\n createdTime: {\n type: \"string\",\n description: \"Creation timestamp (ISO 8601)\",\n },\n modifiedTime: {\n type: \"string\",\n description: \"Last modified timestamp (ISO 8601)\",\n },\n owners: {\n type: \"array\",\n description: \"List of file owners\",\n items: {\n type: \"object\",\n properties: {\n displayName: { type: \"string\" },\n emailAddress: { type: \"string\" },\n },\n },\n },\n shared: { type: \"boolean\", description: \"Whether the file is shared\" },\n starred: {\n type: \"boolean\",\n description: \"Whether the file is starred\",\n },\n description: { type: \"string\", description: \"File description\" },\n webViewLink: {\n type: \"string\",\n description: \"Link to view file in browser\",\n },\n parents: {\n type: \"array\",\n description: \"IDs of parent folders\",\n items: { type: \"string\" },\n },\n },\n },\n },\n {\n name: \"export_file\",\n description: \"Export Workspace files to other formats\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: {\n type: \"string\",\n description: \"ID of the Google Doc, Sheet, or Slides to export\",\n },\n format: {\n type: \"string\",\n description: \"Export format: pdf, docx (Docs), xlsx/csv/tsv (Sheets), pptx (Slides)\",\n enum: [\"pdf\", \"docx\", \"xlsx\", \"pptx\", \"csv\", \"tsv\", \"odt\", \"ods\", \"odp\"],\n },\n outputPath: {\n type: \"string\",\n description: \"Optional directory path to save the file (returns base64 if not provided)\",\n },\n },\n required: [\"fileId\", \"format\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n fileName: { type: \"string\", description: \"Original file name\" },\n format: { type: \"string\", description: \"Export format used\" },\n outputPath: {\n type: \"string\",\n description: \"Path where file was saved (if outputPath provided)\",\n },\n size: { type: \"number\", description: \"File size in bytes\" },\n base64Content: {\n type: \"string\",\n description: \"Base64-encoded content (if no outputPath)\",\n },\n },\n },\n },\n // Sharing tools\n {\n name: \"share_file\",\n description: \"Share a file with a user, group, domain, or make public\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"File ID to share\" },\n role: {\n type: \"string\",\n enum: [\"reader\", \"commenter\", \"writer\", \"organizer\"],\n description: \"Permission role\",\n },\n type: {\n type: \"string\",\n enum: [\"user\", \"group\", \"domain\", \"anyone\"],\n description: \"Permission type\",\n },\n emailAddress: {\n type: \"string\",\n description: \"Email (required for user/group)\",\n },\n domain: {\n type: \"string\",\n description: \"Domain (required for domain type)\",\n },\n sendNotificationEmail: {\n type: \"boolean\",\n description: \"Send notification email (default: true)\",\n },\n emailMessage: {\n type: \"string\",\n description: \"Custom message for notification\",\n },\n },\n required: [\"fileId\", \"role\", \"type\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n fileName: { type: \"string\", description: \"Name of the shared file\" },\n permissionId: { type: \"string\", description: \"Created permission ID\" },\n role: { type: \"string\", description: \"Permission role granted\" },\n target: { type: \"string\", description: \"Who the file was shared with\" },\n },\n },\n },\n {\n name: \"get_sharing\",\n description: \"Get sharing settings and permissions for a file\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"File ID\" },\n },\n required: [\"fileId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n fileName: { type: \"string\", description: \"Name of the file\" },\n webViewLink: {\n type: \"string\",\n description: \"Link to view file in browser\",\n },\n permissions: {\n type: \"array\",\n description: \"List of permissions on the file\",\n items: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Permission ID\" },\n role: {\n type: \"string\",\n description: \"Permission role\",\n enum: [\"owner\", \"organizer\", \"fileOrganizer\", \"writer\", \"commenter\", \"reader\"],\n },\n type: {\n type: \"string\",\n description: \"Permission type\",\n enum: [\"user\", \"group\", \"domain\", \"anyone\"],\n },\n emailAddress: {\n type: \"string\",\n description: \"Email address (for user/group)\",\n },\n domain: {\n type: \"string\",\n description: \"Domain (for domain type)\",\n },\n displayName: {\n type: \"string\",\n description: \"Display name of the user/group\",\n },\n },\n },\n },\n },\n },\n },\n // Revision tools\n {\n name: \"list_revisions\",\n description: \"List file version history\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"File ID\" },\n pageSize: {\n type: \"number\",\n description: \"Max revisions to return (default 100, max 1000)\",\n },\n },\n required: [\"fileId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n fileName: { type: \"string\", description: \"Name of the file\" },\n revisions: {\n type: \"array\",\n description: \"List of file revisions\",\n items: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Revision ID\" },\n modifiedTime: {\n type: \"string\",\n description: \"When revision was created (ISO 8601)\",\n },\n size: {\n type: \"string\",\n description: \"Size of revision in bytes\",\n },\n keepForever: {\n type: \"boolean\",\n description: \"Whether revision is pinned\",\n },\n lastModifyingUser: {\n type: \"object\",\n description: \"User who created this revision\",\n properties: {\n displayName: { type: \"string\" },\n emailAddress: { type: \"string\" },\n },\n },\n },\n },\n },\n },\n },\n },\n {\n name: \"restore_revision\",\n description: \"Restore file to previous revision\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"File ID\" },\n revisionId: { type: \"string\", description: \"Revision ID to restore\" },\n },\n required: [\"fileId\", \"revisionId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n fileName: { type: \"string\", description: \"Name of the restored file\" },\n revisionId: {\n type: \"string\",\n description: \"Revision that was restored\",\n },\n },\n },\n },\n // Binary file tools\n {\n name: \"download_file\",\n description: \"Download a file as base64 or to disk\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"File ID\" },\n outputPath: {\n type: \"string\",\n description: \"Directory to save file (optional, returns base64 if not provided)\",\n },\n },\n required: [\"fileId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n fileName: {\n type: \"string\",\n description: \"Name of the downloaded file\",\n },\n mimeType: { type: \"string\", description: \"MIME type of the file\" },\n size: { type: \"number\", description: \"File size in bytes\" },\n outputPath: {\n type: \"string\",\n description: \"Path where file was saved (if outputPath provided)\",\n },\n base64Content: {\n type: \"string\",\n description: \"Base64-encoded content (if no outputPath)\",\n },\n },\n },\n },\n {\n name: \"upload_file\",\n description: \"Upload file from disk or base64\",\n inputSchema: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"File name with extension\" },\n sourcePath: { type: \"string\", description: \"Path to source file\" },\n base64Content: {\n type: \"string\",\n description: \"Base64-encoded content\",\n },\n mimeType: {\n type: \"string\",\n description: \"MIME type (auto-detected from extension if omitted)\",\n },\n folderId: {\n type: \"string\",\n description: \"Destination folder ID (mutually exclusive with folderPath)\",\n },\n folderPath: {\n type: \"string\",\n description:\n \"Destination folder path like '/Documents/Uploads' (creates folders if needed, mutually exclusive with folderId)\",\n },\n },\n required: [\"name\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Uploaded file ID\" },\n name: { type: \"string\", description: \"Uploaded file name\" },\n webViewLink: { type: \"string\", description: \"Link to view the file\" },\n },\n },\n },\n // Metadata tools\n {\n name: \"get_storage_quota\",\n description: \"Get Google Drive storage quota and usage\",\n inputSchema: {\n type: \"object\",\n properties: {},\n required: [],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n user: {\n type: \"object\",\n description: \"User information\",\n properties: {\n displayName: { type: \"string\" },\n emailAddress: { type: \"string\" },\n },\n },\n storageQuota: {\n type: \"object\",\n description: \"Storage quota details\",\n properties: {\n limit: {\n type: \"string\",\n description: \"Total storage limit in bytes (null if unlimited)\",\n },\n usage: { type: \"string\", description: \"Total bytes used\" },\n usageInDrive: {\n type: \"string\",\n description: \"Bytes used in Drive\",\n },\n usageInDriveTrash: {\n type: \"string\",\n description: \"Bytes used in Drive trash\",\n },\n },\n },\n },\n },\n },\n {\n name: \"star_file\",\n description: \"Star or unstar a file in Google Drive\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"File ID\" },\n starred: {\n type: \"boolean\",\n description: \"true to star, false to unstar\",\n },\n },\n required: [\"fileId\", \"starred\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\", description: \"Whether the operation succeeded\" },\n fileId: { type: \"string\", description: \"File ID\" },\n starred: { type: \"boolean\", description: \"Current starred status\" },\n },\n },\n },\n // File path resolution\n {\n name: \"resolve_file_path\",\n description: \"Resolve file path to ID\",\n inputSchema: {\n type: \"object\",\n properties: {\n path: {\n type: \"string\",\n description:\n \"File path to resolve (e.g., 'Documents/Projects/Budget.xlsx' or '/My Folder/report.pdf')\",\n },\n type: {\n type: \"string\",\n description: \"Type of item to find: 'file', 'folder', or 'any' (default)\",\n enum: [\"file\", \"folder\", \"any\"],\n },\n },\n required: [\"path\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"File ID\" },\n name: { type: \"string\", description: \"File name\" },\n path: { type: \"string\", description: \"Full resolved path\" },\n mimeType: { type: \"string\", description: \"MIME type\" },\n modifiedTime: {\n type: \"string\",\n description: \"Last modified timestamp\",\n },\n },\n },\n },\n // Batch operations\n {\n name: \"batch_delete\",\n description: \"Batch move files to trash (max 100 per batch)\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileIds: {\n type: \"array\",\n description: \"Array of file IDs to delete (max 100)\",\n items: { type: \"string\" },\n },\n },\n required: [\"fileIds\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n succeeded: { type: \"number\", description: \"Number of files successfully deleted\" },\n failed: { type: \"number\", description: \"Number of files that failed\" },\n errors: {\n type: \"array\",\n description: \"List of errors for failed operations\",\n items: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\" },\n error: { type: \"string\" },\n },\n },\n },\n },\n },\n },\n {\n name: \"batch_restore\",\n description: \"Batch restore files from trash (max 100 per batch)\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileIds: {\n type: \"array\",\n description: \"Array of file IDs to restore from trash (max 100)\",\n items: { type: \"string\" },\n },\n },\n required: [\"fileIds\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n succeeded: { type: \"number\", description: \"Number of files successfully restored\" },\n failed: { type: \"number\", description: \"Number of files that failed\" },\n errors: {\n type: \"array\",\n description: \"List of errors for failed operations\",\n items: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\" },\n error: { type: \"string\" },\n },\n },\n },\n },\n },\n },\n {\n name: \"batch_move\",\n description: \"Batch move files to folder (max 100 per batch)\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileIds: {\n type: \"array\",\n description: \"Array of file IDs to move (max 100)\",\n items: { type: \"string\" },\n },\n destinationFolderId: {\n type: \"string\",\n description: \"Destination folder ID (mutually exclusive with destinationPath)\",\n },\n destinationPath: {\n type: \"string\",\n description:\n \"Destination folder path like '/Archive/2024' (creates folders if needed, mutually exclusive with destinationFolderId)\",\n },\n },\n required: [\"fileIds\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n succeeded: { type: \"number\", description: \"Number of files successfully moved\" },\n failed: { type: \"number\", description: \"Number of files that failed\" },\n destinationFolder: {\n type: \"object\",\n description: \"Destination folder info\",\n properties: {\n id: { type: \"string\" },\n name: { type: \"string\" },\n },\n },\n errors: {\n type: \"array\",\n description: \"List of errors for failed operations\",\n items: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\" },\n error: { type: \"string\" },\n },\n },\n },\n },\n },\n },\n {\n name: \"batch_share\",\n description: \"Batch share files with a user (max 100 per batch)\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileIds: {\n type: \"array\",\n description: \"Array of file IDs to share (max 100)\",\n items: { type: \"string\" },\n },\n email: { type: \"string\", description: \"Email address to share with\" },\n role: {\n type: \"string\",\n description: \"Permission role\",\n enum: [\"reader\", \"writer\", \"commenter\"],\n },\n sendNotification: {\n type: \"boolean\",\n description: \"(optional, default: true) Send email notification\",\n },\n },\n required: [\"fileIds\", \"email\", \"role\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n succeeded: { type: \"number\", description: \"Number of files successfully shared\" },\n failed: { type: \"number\", description: \"Number of files that failed\" },\n sharedWith: { type: \"string\", description: \"Email address files were shared with\" },\n role: { type: \"string\", description: \"Permission role granted\" },\n errors: {\n type: \"array\",\n description: \"List of errors for failed operations\",\n items: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\" },\n error: { type: \"string\" },\n },\n },\n },\n },\n },\n },\n // Permission management\n {\n name: \"remove_permission\",\n description: \"Remove sharing permission from a file\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"File ID\" },\n permissionId: {\n type: \"string\",\n description: \"Permission ID (from getSharing)\",\n },\n email: {\n type: \"string\",\n description: \"Email address to remove (alternative to permissionId)\",\n },\n },\n required: [\"fileId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n fileName: { type: \"string\", description: \"Name of the file\" },\n removedTarget: {\n type: \"string\",\n description: \"Email or permission ID that was removed\",\n },\n },\n },\n },\n // Trash management\n {\n name: \"list_trash\",\n description: \"List files in trash\",\n inputSchema: {\n type: \"object\",\n properties: {\n pageSize: {\n type: \"number\",\n description: \"Items per page (default 50, max 100)\",\n },\n pageToken: { type: \"string\", description: \"Token for next page\" },\n },\n },\n outputSchema: {\n type: \"object\",\n properties: {\n files: {\n type: \"array\",\n description: \"Files in trash\",\n items: {\n type: \"object\",\n properties: {\n id: { type: \"string\" },\n name: { type: \"string\" },\n mimeType: { type: \"string\" },\n size: { type: \"string\" },\n trashedTime: { type: \"string\" },\n },\n },\n },\n nextPageToken: { type: \"string\", description: \"Token for next page\" },\n },\n },\n },\n {\n name: \"restore_from_trash\",\n description: \"Restore a file from trash\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"File ID to restore\" },\n destinationFolderId: {\n type: \"string\",\n description:\n \"Optional destination folder ID (mutually exclusive with destinationPath). If not provided, restores to original location.\",\n },\n destinationPath: {\n type: \"string\",\n description:\n \"Optional destination folder path like '/Documents/Restored' (mutually exclusive with destinationFolderId). If not provided, restores to original location.\",\n },\n },\n required: [\"fileId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n fileName: { type: \"string\", description: \"Name of the restored file\" },\n restored: {\n type: \"boolean\",\n description: \"Whether the file was restored\",\n },\n destinationFolder: {\n type: \"object\",\n description: \"Destination folder info (if moved)\",\n properties: {\n id: { type: \"string\" },\n name: { type: \"string\" },\n },\n },\n },\n },\n },\n {\n name: \"empty_trash\",\n description: \"Permanently delete all files in trash\",\n inputSchema: {\n type: \"object\",\n properties: {\n confirm: {\n type: \"boolean\",\n description: \"Must be true to confirm permanent deletion\",\n },\n driveId: {\n type: \"string\",\n description:\n \"Optional shared drive ID. If provided, empties trash of that shared drive instead of personal drive.\",\n },\n },\n required: [\"confirm\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n itemsDeleted: {\n type: \"number\",\n description: \"Number of items permanently deleted\",\n },\n driveId: {\n type: \"string\",\n description: \"Shared drive ID if specified\",\n },\n },\n },\n },\n {\n name: \"get_folder_tree\",\n description: \"Get folder tree structure (max depth 5, truncates at 100 items per folder)\",\n inputSchema: {\n type: \"object\",\n properties: {\n folderId: {\n type: \"string\",\n description:\n \"(optional) Folder ID to start from (defaults to root, mutually exclusive with folderPath)\",\n },\n folderPath: {\n type: \"string\",\n description:\n \"(optional) Folder path like '/Documents/Projects' (mutually exclusive with folderId)\",\n },\n depth: {\n type: \"number\",\n description:\n \"(optional, default: 2) Maximum depth to traverse (1-5). Higher values make more API calls.\",\n },\n },\n required: [],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Folder ID\" },\n name: { type: \"string\", description: \"Folder name\" },\n path: { type: \"string\", description: \"Folder path\" },\n children: {\n type: \"array\",\n description: \"Recursive array of files and folders\",\n items: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Item ID\" },\n name: { type: \"string\", description: \"Item name\" },\n type: { type: \"string\", description: \"'folder' or 'file'\" },\n mimeType: { type: \"string\", description: \"MIME type for files\" },\n children: {\n type: \"array\",\n description: \"Children (for folders only)\",\n },\n truncated: {\n type: \"boolean\",\n description: \"True if folder contents were truncated at 100 items\",\n },\n },\n },\n },\n truncated: {\n type: \"boolean\",\n description: \"True if root folder contents were truncated at 100 items\",\n },\n },\n },\n },\n];\n\n// Docs tools\nexport const docsTools: ToolDefinition[] = [\n {\n name: \"create_google_doc\",\n description: \"Create a new Google Doc\",\n inputSchema: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"Doc name\" },\n content: { type: \"string\", description: \"Doc content\" },\n parentFolderId: {\n type: \"string\",\n description: \"Parent folder ID (mutually exclusive with parentPath)\",\n },\n parentPath: {\n type: \"string\",\n description:\n \"Parent folder path like '/Documents/Reports' (creates folders if needed, mutually exclusive with parentFolderId)\",\n },\n },\n required: [\"name\", \"content\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Created document ID\" },\n name: { type: \"string\", description: \"Created document name\" },\n webViewLink: {\n type: \"string\",\n description: \"Link to view the document\",\n },\n },\n },\n },\n {\n name: \"update_google_doc\",\n description: \"Replace content in a Google Doc\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"Doc ID\" },\n content: { type: \"string\", description: \"New content\" },\n },\n required: [\"documentId\", \"content\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n title: { type: \"string\", description: \"Document title\" },\n updated: {\n type: \"boolean\",\n description: \"Whether the update succeeded\",\n },\n },\n },\n },\n {\n name: \"get_google_doc_content\",\n description: \"Read content from a Google Doc\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"Document ID\" },\n },\n required: [\"documentId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"Document ID\" },\n title: { type: \"string\", description: \"Document title\" },\n content: {\n type: \"array\",\n description: \"Document content segments with indices\",\n items: {\n type: \"object\",\n properties: {\n startIndex: {\n type: \"number\",\n description: \"Start character index\",\n },\n endIndex: { type: \"number\", description: \"End character index\" },\n text: { type: \"string\", description: \"Text content\" },\n },\n },\n },\n totalLength: { type: \"number\", description: \"Total character count\" },\n },\n },\n },\n {\n name: \"append_to_doc\",\n description: \"Append text to the end of a Google Doc\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"Document ID\" },\n text: { type: \"string\", description: \"Text to append\" },\n insertNewline: {\n type: \"boolean\",\n description: \"Insert newline before text (default: true)\",\n },\n },\n required: [\"documentId\", \"text\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n title: { type: \"string\", description: \"Document title\" },\n charactersAdded: {\n type: \"number\",\n description: \"Number of characters added\",\n },\n },\n },\n },\n {\n name: \"insert_text_in_doc\",\n description: \"Insert text at a position in a Doc\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"Document ID\" },\n text: { type: \"string\", description: \"Text to insert\" },\n index: {\n type: \"number\",\n description:\n \"Character index to insert at (1 = beginning of document content). Get indices from getGoogleDocContent.\",\n },\n },\n required: [\"documentId\", \"text\", \"index\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n title: { type: \"string\", description: \"Document title\" },\n index: { type: \"number\", description: \"Index where text was inserted\" },\n charactersInserted: {\n type: \"number\",\n description: \"Number of characters inserted\",\n },\n },\n },\n },\n {\n name: \"delete_text_in_doc\",\n description: \"Delete text range from a Google Doc\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"Document ID\" },\n startIndex: {\n type: \"number\",\n description: \"Start index of range to delete (inclusive, 1-based)\",\n },\n endIndex: {\n type: \"number\",\n description: \"End index of range to delete (exclusive, 1-based)\",\n },\n },\n required: [\"documentId\", \"startIndex\", \"endIndex\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n title: { type: \"string\", description: \"Document title\" },\n startIndex: { type: \"number\", description: \"Start of deleted range\" },\n endIndex: { type: \"number\", description: \"End of deleted range\" },\n charactersDeleted: {\n type: \"number\",\n description: \"Number of characters deleted\",\n },\n },\n },\n },\n {\n name: \"replace_text_in_doc\",\n description: \"Find and replace text in a Doc\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"Document ID\" },\n searchText: { type: \"string\", description: \"Text to search for\" },\n replaceText: {\n type: \"string\",\n description: \"Text to replace with (use empty string to delete)\",\n },\n matchCase: {\n type: \"boolean\",\n description: \"Match case (default: true)\",\n },\n },\n required: [\"documentId\", \"searchText\", \"replaceText\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n title: { type: \"string\", description: \"Document title\" },\n occurrencesChanged: {\n type: \"number\",\n description: \"Number of occurrences replaced\",\n },\n },\n },\n },\n {\n name: \"format_google_doc_range\",\n description: \"Format text and paragraphs in a Doc\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"Document ID\" },\n startIndex: {\n type: \"number\",\n description: \"Start index (1-based, optional - defaults to document start)\",\n },\n endIndex: {\n type: \"number\",\n description: \"End index (1-based, optional - defaults to document end)\",\n },\n // Text formatting\n bold: { type: \"boolean\", description: \"Make text bold\" },\n italic: { type: \"boolean\", description: \"Make text italic\" },\n underline: { type: \"boolean\", description: \"Underline text\" },\n strikethrough: { type: \"boolean\", description: \"Strikethrough text\" },\n fontSize: { type: \"number\", description: \"Font size in points\" },\n fontFamily: { type: \"string\", description: \"Font family name\" },\n foregroundColor: {\n type: \"object\",\n description: \"Text color (RGB values 0-1)\",\n properties: {\n red: { type: \"number\" },\n green: { type: \"number\" },\n blue: { type: \"number\" },\n },\n },\n // Paragraph formatting\n alignment: {\n type: \"string\",\n description: \"Text alignment\",\n enum: [\"START\", \"CENTER\", \"END\", \"JUSTIFIED\"],\n },\n lineSpacing: { type: \"number\", description: \"Line spacing multiplier\" },\n spaceAbove: {\n type: \"number\",\n description: \"Space above paragraph in points\",\n },\n spaceBelow: {\n type: \"number\",\n description: \"Space below paragraph in points\",\n },\n namedStyleType: {\n type: \"string\",\n description: \"Paragraph style\",\n enum: [\n \"NORMAL_TEXT\",\n \"TITLE\",\n \"SUBTITLE\",\n \"HEADING_1\",\n \"HEADING_2\",\n \"HEADING_3\",\n \"HEADING_4\",\n \"HEADING_5\",\n \"HEADING_6\",\n ],\n },\n },\n required: [\"documentId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n startIndex: { type: \"number\", description: \"Start of formatted range\" },\n endIndex: { type: \"number\", description: \"End of formatted range\" },\n formatsApplied: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"List of formats applied\",\n },\n },\n },\n },\n];\n\n// Sheets tools\nexport const sheetsTools: ToolDefinition[] = [\n {\n name: \"create_google_sheet\",\n description: \"Create a new Google Sheet\",\n inputSchema: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"Sheet name\" },\n data: {\n type: \"array\",\n description: \"Data as array of arrays\",\n items: { type: \"array\", items: { type: \"string\" } },\n },\n parentFolderId: {\n type: \"string\",\n description: \"Parent folder ID (mutually exclusive with parentPath)\",\n },\n parentPath: {\n type: \"string\",\n description:\n \"Parent folder path like '/Data/Spreadsheets' (creates folders if needed, mutually exclusive with parentFolderId)\",\n },\n valueInputOption: {\n type: \"string\",\n enum: [\"RAW\", \"USER_ENTERED\"],\n description:\n \"RAW (default): Values stored exactly as provided - formulas stored as text strings. Safe for untrusted data. USER_ENTERED: Values parsed like spreadsheet UI - formulas (=SUM, =IF, etc.) are evaluated. SECURITY WARNING: USER_ENTERED can execute formulas, only use with trusted data, never with user-provided input that could contain malicious formulas like =IMPORTDATA() or =IMPORTRANGE().\",\n },\n },\n required: [\"name\", \"data\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Created spreadsheet ID\" },\n name: { type: \"string\", description: \"Created spreadsheet name\" },\n },\n },\n },\n {\n name: \"update_google_sheet\",\n description: \"Update a Google Sheet range\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Sheet ID\" },\n range: {\n type: \"string\",\n description: \"Range to update (e.g., 'Sheet1!A1:C10')\",\n },\n data: {\n type: \"array\",\n description: \"2D array of values to write\",\n items: { type: \"array\", items: { type: \"string\" } },\n },\n valueInputOption: {\n type: \"string\",\n enum: [\"RAW\", \"USER_ENTERED\"],\n description:\n \"RAW (default): Values stored exactly as provided - formulas stored as text strings. Safe for untrusted data. USER_ENTERED: Values parsed like spreadsheet UI - formulas (=SUM, =IF, etc.) are evaluated. SECURITY WARNING: USER_ENTERED can execute formulas, only use with trusted data, never with user-provided input that could contain malicious formulas like =IMPORTDATA() or =IMPORTRANGE().\",\n },\n },\n required: [\"spreadsheetId\", \"range\", \"data\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n range: { type: \"string\", description: \"Range that was updated\" },\n updated: {\n type: \"boolean\",\n description: \"Whether the update succeeded\",\n },\n },\n },\n },\n {\n name: \"get_google_sheet_content\",\n description: \"Read content from a Google Sheet\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\n range: {\n type: \"string\",\n description:\n \"Range in A1 notation (e.g., 'Sheet1!A1:C10'). Optional - if omitted, returns all data from the first sheet.\",\n },\n },\n required: [\"spreadsheetId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\n range: { type: \"string\", description: \"Range that was retrieved\" },\n values: {\n type: \"array\",\n description: \"2D array of cell values (rows x columns)\",\n items: {\n type: \"array\",\n items: { type: \"string\", description: \"Cell value\" },\n },\n },\n rowCount: { type: \"number\", description: \"Number of rows returned\" },\n columnCount: {\n type: \"number\",\n description: \"Number of columns returned\",\n },\n },\n },\n },\n {\n name: \"format_google_sheet_cells\",\n description: \"Format cells in a Google Sheet\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\n range: {\n type: \"string\",\n description: \"Range to format (e.g., 'Sheet1!A1:C10' or 'A1:C10')\",\n },\n // Cell formatting\n backgroundColor: {\n type: \"object\",\n description: \"Background color (RGB values 0-1)\",\n properties: {\n red: { type: \"number\" },\n green: { type: \"number\" },\n blue: { type: \"number\" },\n },\n },\n horizontalAlignment: {\n type: \"string\",\n description: \"Horizontal alignment\",\n enum: [\"LEFT\", \"CENTER\", \"RIGHT\"],\n },\n verticalAlignment: {\n type: \"string\",\n description: \"Vertical alignment\",\n enum: [\"TOP\", \"MIDDLE\", \"BOTTOM\"],\n },\n wrapStrategy: {\n type: \"string\",\n description: \"Text wrapping\",\n enum: [\"OVERFLOW_CELL\", \"CLIP\", \"WRAP\"],\n },\n // Text formatting\n bold: { type: \"boolean\", description: \"Make text bold\" },\n italic: { type: \"boolean\", description: \"Make text italic\" },\n strikethrough: { type: \"boolean\", description: \"Strikethrough text\" },\n underline: { type: \"boolean\", description: \"Underline text\" },\n fontSize: { type: \"number\", description: \"Font size in points\" },\n fontFamily: { type: \"string\", description: \"Font family name\" },\n foregroundColor: {\n type: \"object\",\n description: \"Text color (RGB values 0-1)\",\n properties: {\n red: { type: \"number\" },\n green: { type: \"number\" },\n blue: { type: \"number\" },\n },\n },\n // Number formatting\n numberFormat: {\n type: \"object\",\n description: \"Number format settings\",\n properties: {\n pattern: {\n type: \"string\",\n description: \"Format pattern (e.g., '#,##0.00', 'yyyy-mm-dd', '$#,##0.00', '0.00%')\",\n },\n type: {\n type: \"string\",\n description: \"Format type\",\n enum: [\"NUMBER\", \"CURRENCY\", \"PERCENT\", \"DATE\", \"TIME\", \"DATE_TIME\", \"SCIENTIFIC\"],\n },\n },\n },\n // Border formatting\n borders: {\n type: \"object\",\n description: \"Border settings\",\n properties: {\n style: {\n type: \"string\",\n description: \"Border style\",\n enum: [\"SOLID\", \"DASHED\", \"DOTTED\", \"DOUBLE\"],\n },\n width: { type: \"number\", description: \"Border width (1-3)\" },\n color: {\n type: \"object\",\n description: \"Border color (RGB values 0-1)\",\n properties: {\n red: { type: \"number\" },\n green: { type: \"number\" },\n blue: { type: \"number\" },\n },\n },\n top: {\n type: \"boolean\",\n description: \"Apply to top border (default: true)\",\n },\n bottom: {\n type: \"boolean\",\n description: \"Apply to bottom border (default: true)\",\n },\n left: {\n type: \"boolean\",\n description: \"Apply to left border (default: true)\",\n },\n right: {\n type: \"boolean\",\n description: \"Apply to right border (default: true)\",\n },\n innerHorizontal: {\n type: \"boolean\",\n description: \"Apply to inner horizontal borders\",\n },\n innerVertical: {\n type: \"boolean\",\n description: \"Apply to inner vertical borders\",\n },\n },\n },\n },\n required: [\"spreadsheetId\", \"range\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n range: { type: \"string\", description: \"Range that was formatted\" },\n applied: {\n type: \"boolean\",\n description: \"Whether formatting was applied\",\n },\n },\n },\n },\n {\n name: \"merge_google_sheet_cells\",\n description: \"Merge cells in a Google Sheet\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\n range: {\n type: \"string\",\n description: \"Range to merge (e.g., 'A1:C3')\",\n },\n mergeType: {\n type: \"string\",\n description: \"Merge type\",\n enum: [\"MERGE_ALL\", \"MERGE_COLUMNS\", \"MERGE_ROWS\"],\n },\n },\n required: [\"spreadsheetId\", \"range\", \"mergeType\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n range: { type: \"string\", description: \"Range that was merged\" },\n mergeType: { type: \"string\", description: \"Type of merge performed\" },\n },\n },\n },\n {\n name: \"add_google_sheet_conditional_format\",\n description: \"Add conditional formatting to a Sheet\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\n range: {\n type: \"string\",\n description: \"Range to apply formatting (e.g., 'A1:C10')\",\n },\n condition: {\n type: \"object\",\n description: \"Condition configuration\",\n properties: {\n type: {\n type: \"string\",\n description: \"Condition type\",\n enum: [\n \"NUMBER_GREATER\",\n \"NUMBER_LESS\",\n \"TEXT_CONTAINS\",\n \"TEXT_STARTS_WITH\",\n \"TEXT_ENDS_WITH\",\n \"CUSTOM_FORMULA\",\n ],\n },\n value: {\n type: \"string\",\n description: \"Value to compare or formula\",\n },\n },\n },\n format: {\n type: \"object\",\n description: \"Format to apply when condition is true\",\n properties: {\n backgroundColor: {\n type: \"object\",\n properties: {\n red: { type: \"number\" },\n green: { type: \"number\" },\n blue: { type: \"number\" },\n },\n },\n textFormat: {\n type: \"object\",\n properties: {\n bold: { type: \"boolean\" },\n foregroundColor: {\n type: \"object\",\n properties: {\n red: { type: \"number\" },\n green: { type: \"number\" },\n blue: { type: \"number\" },\n },\n },\n },\n },\n },\n },\n },\n required: [\"spreadsheetId\", \"range\", \"condition\", \"format\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n range: {\n type: \"string\",\n description: \"Range where conditional format was applied\",\n },\n conditionType: {\n type: \"string\",\n description: \"Type of condition applied\",\n },\n },\n },\n },\n {\n name: \"sheet_tabs\",\n description: \"Manage tabs in a spreadsheet: list, create, delete, or rename\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\n action: {\n type: \"string\",\n enum: [\"list\", \"create\", \"delete\", \"rename\"],\n description: \"Action to perform\",\n },\n title: { type: \"string\", description: \"Tab title (required for create/delete)\" },\n index: { type: \"number\", description: \"(optional) Position for new tab (create only)\" },\n currentTitle: { type: \"string\", description: \"Current title (required for rename)\" },\n newTitle: { type: \"string\", description: \"New title (required for rename)\" },\n },\n required: [\"spreadsheetId\", \"action\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n action: { type: \"string\", description: \"Action performed\" },\n tabs: {\n type: \"array\",\n description: \"List of tabs (for list action)\",\n items: {\n type: \"object\",\n properties: {\n sheetId: { type: \"number\", description: \"Sheet ID\" },\n title: { type: \"string\", description: \"Tab title\" },\n index: { type: \"number\", description: \"Tab position\" },\n },\n },\n },\n sheetId: { type: \"number\", description: \"Sheet ID (for create/delete/rename)\" },\n title: { type: \"string\", description: \"Tab title\" },\n },\n },\n },\n];\n\n// Slides tools\nexport const slidesTools: ToolDefinition[] = [\n {\n name: \"create_google_slides\",\n description: \"Create a new Google Slides presentation\",\n inputSchema: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"Presentation name\" },\n slides: {\n type: \"array\",\n description: \"Array of slide objects\",\n items: {\n type: \"object\",\n properties: {\n title: { type: \"string\" },\n content: { type: \"string\" },\n },\n },\n },\n parentFolderId: {\n type: \"string\",\n description: \"Parent folder ID (mutually exclusive with parentPath)\",\n },\n parentPath: {\n type: \"string\",\n description:\n \"Parent folder path like '/Presentations/2024' (creates folders if needed, mutually exclusive with parentFolderId)\",\n },\n },\n required: [\"name\", \"slides\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Created presentation ID\" },\n name: { type: \"string\", description: \"Created presentation name\" },\n webViewLink: {\n type: \"string\",\n description: \"Link to view the presentation\",\n },\n },\n },\n },\n {\n name: \"update_google_slides\",\n description: \"Update a Google Slides presentation\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n slides: {\n type: \"array\",\n description: \"Array of slide objects to replace existing slides\",\n items: {\n type: \"object\",\n properties: {\n title: { type: \"string\" },\n content: { type: \"string\" },\n },\n },\n },\n },\n required: [\"presentationId\", \"slides\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n slideCount: {\n type: \"number\",\n description: \"Number of slides after update\",\n },\n webViewLink: {\n type: \"string\",\n description: \"Link to view the presentation\",\n },\n },\n },\n },\n {\n name: \"get_google_slides_content\",\n description: \"Read content from Google Slides\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n slideIndex: {\n type: \"number\",\n description: \"Specific slide index (optional)\",\n },\n },\n required: [\"presentationId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n title: { type: \"string\", description: \"Presentation title\" },\n slideCount: { type: \"number\", description: \"Total number of slides\" },\n slides: {\n type: \"array\",\n description: \"List of slides with their elements\",\n items: {\n type: \"object\",\n properties: {\n index: { type: \"number\", description: \"Slide index (0-based)\" },\n objectId: { type: \"string\", description: \"Slide object ID\" },\n elements: {\n type: \"array\",\n description: \"Elements on the slide\",\n items: {\n type: \"object\",\n properties: {\n objectId: {\n type: \"string\",\n description: \"Element object ID\",\n },\n type: {\n type: \"string\",\n description: \"Element type\",\n enum: [\"textBox\", \"shape\", \"image\", \"video\", \"table\"],\n },\n text: {\n type: \"string\",\n description: \"Text content (for text elements)\",\n },\n shapeType: {\n type: \"string\",\n description: \"Shape type (for shapes)\",\n },\n },\n },\n },\n },\n },\n },\n },\n },\n },\n {\n name: \"format_slides_text\",\n description: \"Format text styling in Google Slides\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n objectId: { type: \"string\", description: \"Text element object ID\" },\n startIndex: { type: \"number\", description: \"Start index (0-based, optional)\" },\n endIndex: { type: \"number\", description: \"End index (0-based, optional)\" },\n bold: { type: \"boolean\", description: \"Make text bold\" },\n italic: { type: \"boolean\", description: \"Make text italic\" },\n underline: { type: \"boolean\", description: \"Underline text\" },\n strikethrough: { type: \"boolean\", description: \"Strikethrough text\" },\n fontSize: { type: \"number\", description: \"Font size in points\" },\n fontFamily: { type: \"string\", description: \"Font family name\" },\n foregroundColor: {\n type: \"object\",\n description: \"Text color RGB (values 0-1)\",\n properties: {\n red: { type: \"number\" },\n green: { type: \"number\" },\n blue: { type: \"number\" },\n },\n },\n alignment: {\n type: \"string\",\n description: \"Text alignment\",\n enum: [\"START\", \"CENTER\", \"END\", \"JUSTIFIED\"],\n },\n lineSpacing: { type: \"number\", description: \"Line spacing multiplier\" },\n bulletStyle: {\n type: \"string\",\n description: \"Bullet style\",\n enum: [\"NONE\", \"DISC\", \"ARROW\", \"SQUARE\", \"DIAMOND\", \"STAR\", \"NUMBERED\"],\n },\n },\n required: [\"presentationId\", \"objectId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n objectId: { type: \"string\", description: \"Formatted text object ID\" },\n formatsApplied: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"List of formats applied\",\n },\n },\n },\n },\n {\n name: \"format_slides_shape\",\n description: \"Format shape fill and outline in Google Slides\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n objectId: { type: \"string\", description: \"Shape object ID\" },\n backgroundColor: {\n type: \"object\",\n description: \"Shape fill color RGBA (values 0-1)\",\n properties: {\n red: { type: \"number\" },\n green: { type: \"number\" },\n blue: { type: \"number\" },\n alpha: { type: \"number\" },\n },\n },\n outlineColor: {\n type: \"object\",\n description: \"Outline color RGB (values 0-1)\",\n properties: {\n red: { type: \"number\" },\n green: { type: \"number\" },\n blue: { type: \"number\" },\n },\n },\n outlineWeight: { type: \"number\", description: \"Outline thickness in points\" },\n outlineDashStyle: {\n type: \"string\",\n description: \"Outline dash style\",\n enum: [\"SOLID\", \"DOT\", \"DASH\", \"DASH_DOT\", \"LONG_DASH\", \"LONG_DASH_DOT\"],\n },\n },\n required: [\"presentationId\", \"objectId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n objectId: { type: \"string\", description: \"Formatted shape object ID\" },\n formatsApplied: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"List of formats applied\",\n },\n },\n },\n },\n {\n name: \"format_slide_background\",\n description: \"Set slide background color in Google Slides\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n pageObjectIds: {\n type: \"array\",\n description: \"Array of slide IDs to format\",\n items: { type: \"string\" },\n },\n backgroundColor: {\n type: \"object\",\n description: \"Background color RGBA (values 0-1)\",\n properties: {\n red: { type: \"number\" },\n green: { type: \"number\" },\n blue: { type: \"number\" },\n alpha: { type: \"number\" },\n },\n },\n },\n required: [\"presentationId\", \"pageObjectIds\", \"backgroundColor\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n slidesFormatted: { type: \"number\", description: \"Number of slides formatted\" },\n },\n },\n },\n {\n name: \"create_google_slides_text_box\",\n description: \"Create a text box in Google Slides\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n pageObjectId: { type: \"string\", description: \"Slide ID\" },\n text: { type: \"string\", description: \"Text content\" },\n x: {\n type: \"number\",\n description: \"X position in EMU (1 inch = 914400 EMU)\",\n },\n y: { type: \"number\", description: \"Y position in EMU\" },\n width: { type: \"number\", description: \"Width in EMU\" },\n height: { type: \"number\", description: \"Height in EMU\" },\n fontSize: { type: \"number\", description: \"Font size in points\" },\n bold: { type: \"boolean\", description: \"Make text bold\" },\n italic: { type: \"boolean\", description: \"Make text italic\" },\n },\n required: [\"presentationId\", \"pageObjectId\", \"text\", \"x\", \"y\", \"width\", \"height\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n objectId: { type: \"string\", description: \"Created text box object ID\" },\n pageObjectId: {\n type: \"string\",\n description: \"Slide where text box was created\",\n },\n },\n },\n },\n {\n name: \"create_google_slides_shape\",\n description: \"Create a shape in Google Slides\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n pageObjectId: { type: \"string\", description: \"Slide ID\" },\n shapeType: {\n type: \"string\",\n description: \"Shape type\",\n enum: [\"RECTANGLE\", \"ELLIPSE\", \"DIAMOND\", \"TRIANGLE\", \"STAR\", \"ROUND_RECTANGLE\", \"ARROW\"],\n },\n x: {\n type: \"number\",\n description: \"X position in EMU (1 inch = 914400 EMU)\",\n },\n y: { type: \"number\", description: \"Y position in EMU\" },\n width: { type: \"number\", description: \"Width in EMU\" },\n height: { type: \"number\", description: \"Height in EMU\" },\n backgroundColor: {\n type: \"object\",\n description: \"Fill color (RGBA values 0-1)\",\n properties: {\n red: { type: \"number\" },\n green: { type: \"number\" },\n blue: { type: \"number\" },\n alpha: { type: \"number\" },\n },\n },\n },\n required: [\"presentationId\", \"pageObjectId\", \"shapeType\", \"x\", \"y\", \"width\", \"height\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n objectId: { type: \"string\", description: \"Created shape object ID\" },\n pageObjectId: {\n type: \"string\",\n description: \"Slide where shape was created\",\n },\n shapeType: { type: \"string\", description: \"Type of shape created\" },\n },\n },\n },\n {\n name: \"slides_speaker_notes\",\n description: \"Get or update speaker notes for a slide\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n slideIndex: { type: \"number\", description: \"Slide index (0-based)\" },\n action: {\n type: \"string\",\n enum: [\"get\", \"update\"],\n description: \"Action to perform\",\n },\n notes: { type: \"string\", description: \"Notes content (required for update)\" },\n },\n required: [\"presentationId\", \"slideIndex\", \"action\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n action: { type: \"string\", description: \"Action performed\" },\n slideIndex: { type: \"number\", description: \"Slide index\" },\n notes: { type: \"string\", description: \"Speaker notes content\" },\n updated: { type: \"boolean\", description: \"Whether notes were updated (for update action)\" },\n },\n },\n },\n {\n name: \"list_slide_pages\",\n description: \"List slides in a presentation\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n },\n required: [\"presentationId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n pages: {\n type: \"array\",\n description: \"List of slide pages with metadata\",\n items: {\n type: \"object\",\n properties: {\n objectId: {\n type: \"string\",\n description: \"Page object ID (used for slide operations)\",\n },\n index: {\n type: \"number\",\n description: \"Slide position (0-indexed)\",\n },\n pageType: {\n type: \"string\",\n description: \"Page type: SLIDE, MASTER, or LAYOUT\",\n },\n title: {\n type: \"string\",\n description: \"Slide title if available\",\n },\n },\n },\n },\n },\n },\n },\n];\n\n// Unified smart tools\nexport const unifiedTools: ToolDefinition[] = [\n {\n name: \"create_file\",\n description: \"Create file (auto-detects type from name)\",\n inputSchema: {\n type: \"object\",\n properties: {\n name: {\n type: \"string\",\n description:\n \"File name with extension (e.g., 'report.docx', 'data.xlsx', 'deck.pptx', 'notes.txt')\",\n },\n content: {\n description:\n \"File content: string for docs/text, 2D array for sheets, array of {title, content} for slides\",\n oneOf: [\n {\n type: \"string\",\n description: \"Text content for docs or text files\",\n },\n {\n type: \"array\",\n description: \"2D array for sheets\",\n items: { type: \"array\", items: { type: \"string\" } },\n },\n {\n type: \"array\",\n description: \"Slides array\",\n items: {\n type: \"object\",\n properties: {\n title: { type: \"string\" },\n content: { type: \"string\" },\n },\n required: [\"title\", \"content\"],\n },\n },\n ],\n },\n parentFolderId: {\n type: \"string\",\n description: \"Parent folder ID (mutually exclusive with parentPath)\",\n },\n parentPath: {\n type: \"string\",\n description:\n \"Parent folder path like '/Documents/Reports' (creates folders if needed, mutually exclusive with parentFolderId)\",\n },\n type: {\n type: \"string\",\n description: \"Optional explicit type override\",\n enum: [\"doc\", \"sheet\", \"slides\", \"text\"],\n },\n },\n required: [\"name\", \"content\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Created file ID\" },\n name: { type: \"string\", description: \"Created file name\" },\n type: {\n type: \"string\",\n description: \"File type (doc, sheet, slides, or text)\",\n },\n mimeType: { type: \"string\", description: \"Google MIME type\" },\n webViewLink: { type: \"string\", description: \"Link to view the file\" },\n },\n },\n },\n {\n name: \"update_file\",\n description: \"Update file (auto-detects type)\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: {\n type: \"string\",\n description: \"File ID to update (mutually exclusive with filePath)\",\n },\n filePath: {\n type: \"string\",\n description: \"File path like '/Documents/report.docx' (mutually exclusive with fileId)\",\n },\n content: {\n description: \"New content: string for docs/text, 2D array for sheets\",\n oneOf: [\n { type: \"string\", description: \"Text content\" },\n {\n type: \"array\",\n description: \"2D array for sheets\",\n items: { type: \"array\", items: { type: \"string\" } },\n },\n ],\n },\n range: {\n type: \"string\",\n description:\n \"For sheets only: range to update (e.g., 'Sheet1!A1:C10'). Defaults to Sheet1!A1\",\n },\n },\n required: [\"content\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Updated file ID\" },\n name: { type: \"string\", description: \"File name\" },\n type: { type: \"string\", description: \"File type\" },\n updated: { type: \"boolean\", description: \"Whether update succeeded\" },\n },\n },\n },\n {\n name: \"get_file_content\",\n description: \"Get file content (auto-detects type)\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: {\n type: \"string\",\n description: \"File ID to read (mutually exclusive with filePath)\",\n },\n filePath: {\n type: \"string\",\n description: \"File path like '/Documents/report.docx' (mutually exclusive with fileId)\",\n },\n range: {\n type: \"string\",\n description:\n \"For sheets only: range to read (e.g., 'Sheet1!A1:C10'). Defaults to all data\",\n },\n },\n },\n outputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"File ID\" },\n name: { type: \"string\", description: \"File name\" },\n type: {\n type: \"string\",\n description: \"File type (doc, sheet, slides, text, or binary)\",\n },\n mimeType: { type: \"string\", description: \"MIME type\" },\n content: {\n description:\n \"File content: string for docs/text, 2D array for sheets, slides array for presentations\",\n },\n metadata: {\n type: \"object\",\n description: \"Additional metadata\",\n properties: {\n modifiedTime: { type: \"string\" },\n title: { type: \"string\" },\n size: { type: \"string\" },\n rowCount: { type: \"number\" },\n columnCount: { type: \"number\" },\n slideCount: { type: \"number\" },\n },\n },\n },\n },\n },\n];\n\n// Calendar tools\nexport const calendarTools: ToolDefinition[] = [\n {\n name: \"list_calendars\",\n description: \"List all calendars accessible to the user\",\n inputSchema: {\n type: \"object\",\n properties: {\n showHidden: {\n type: \"boolean\",\n description: \"Include hidden calendars (default: false)\",\n },\n showDeleted: {\n type: \"boolean\",\n description: \"Include deleted calendars (default: false)\",\n },\n },\n },\n outputSchema: {\n type: \"object\",\n properties: {\n calendars: {\n type: \"array\",\n description: \"List of calendars\",\n items: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Calendar ID\" },\n summary: { type: \"string\", description: \"Calendar name\" },\n description: { type: \"string\", description: \"Calendar description\" },\n primary: { type: \"boolean\", description: \"Whether this is the primary calendar\" },\n accessRole: {\n type: \"string\",\n description: \"Access role (owner, writer, reader, freeBusyReader)\",\n },\n timeZone: { type: \"string\", description: \"Calendar timezone\" },\n },\n },\n },\n },\n },\n },\n {\n name: \"list_events\",\n description: \"List calendar events (max 2500 per request)\",\n inputSchema: {\n type: \"object\",\n properties: {\n calendarId: {\n type: \"string\",\n description: \"(optional, default: 'primary') Calendar ID\",\n },\n timeMin: {\n type: \"string\",\n description:\n \"(optional) Start of time range (RFC3339 timestamp, e.g., 2024-01-15T00:00:00Z)\",\n },\n timeMax: {\n type: \"string\",\n description: \"(optional) End of time range (RFC3339 timestamp)\",\n },\n query: {\n type: \"string\",\n description: \"(optional) Free text search terms to filter events\",\n },\n maxResults: {\n type: \"number\",\n description: \"(optional, default: 250) Maximum events to return (max 2500)\",\n },\n pageToken: {\n type: \"string\",\n description: \"(optional) Token for pagination\",\n },\n singleEvents: {\n type: \"boolean\",\n description: \"(optional, default: true) Expand recurring events into instances\",\n },\n orderBy: {\n type: \"string\",\n enum: [\"startTime\", \"updated\"],\n description: \"(optional) Sort order (startTime requires singleEvents=true)\",\n },\n },\n },\n outputSchema: {\n type: \"object\",\n properties: {\n events: {\n type: \"array\",\n description: \"List of events\",\n items: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Event ID\" },\n summary: { type: \"string\", description: \"Event title\" },\n description: { type: \"string\", description: \"Event description\" },\n location: { type: \"string\", description: \"Event location\" },\n start: {\n type: \"object\",\n description: \"Start time\",\n properties: {\n dateTime: { type: \"string\", description: \"RFC3339 timestamp (timed events)\" },\n date: { type: \"string\", description: \"YYYY-MM-DD (all-day events)\" },\n timeZone: { type: \"string\", description: \"IANA timezone\" },\n },\n },\n end: {\n type: \"object\",\n description: \"End time\",\n properties: {\n dateTime: { type: \"string\", description: \"RFC3339 timestamp (timed events)\" },\n date: { type: \"string\", description: \"YYYY-MM-DD (all-day events)\" },\n timeZone: { type: \"string\", description: \"IANA timezone\" },\n },\n },\n status: { type: \"string\", description: \"Event status\" },\n htmlLink: { type: \"string\", description: \"Link to event in Google Calendar\" },\n hangoutLink: { type: \"string\", description: \"Google Meet link if present\" },\n },\n },\n },\n nextPageToken: {\n type: \"string\",\n description: \"Token for fetching next page\",\n },\n },\n },\n },\n {\n name: \"get_event\",\n description: \"Get details of a calendar event\",\n inputSchema: {\n type: \"object\",\n properties: {\n calendarId: {\n type: \"string\",\n description: \"Calendar ID (defaults to 'primary')\",\n },\n eventId: {\n type: \"string\",\n description: \"Event ID\",\n },\n },\n required: [\"eventId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Event ID\" },\n summary: { type: \"string\", description: \"Event title\" },\n description: { type: \"string\", description: \"Event description\" },\n location: { type: \"string\", description: \"Event location\" },\n start: {\n type: \"object\",\n description: \"Start time\",\n properties: {\n dateTime: { type: \"string\", description: \"RFC3339 timestamp (timed events)\" },\n date: { type: \"string\", description: \"YYYY-MM-DD (all-day events)\" },\n timeZone: { type: \"string\", description: \"IANA timezone\" },\n },\n },\n end: {\n type: \"object\",\n description: \"End time\",\n properties: {\n dateTime: { type: \"string\", description: \"RFC3339 timestamp (timed events)\" },\n date: { type: \"string\", description: \"YYYY-MM-DD (all-day events)\" },\n timeZone: { type: \"string\", description: \"IANA timezone\" },\n },\n },\n status: { type: \"string\", description: \"Event status\" },\n htmlLink: { type: \"string\", description: \"Link to event\" },\n hangoutLink: { type: \"string\", description: \"Google Meet link\" },\n attendees: {\n type: \"array\",\n description: \"Event attendees\",\n items: {\n type: \"object\",\n properties: {\n email: { type: \"string\" },\n displayName: { type: \"string\" },\n responseStatus: { type: \"string\" },\n },\n },\n },\n organizer: {\n type: \"object\",\n description: \"Event organizer\",\n properties: {\n email: { type: \"string\", description: \"Organizer email\" },\n displayName: { type: \"string\", description: \"Organizer name\" },\n self: { type: \"boolean\", description: \"Whether you are the organizer\" },\n },\n },\n recurrence: {\n type: \"array\",\n description: \"Recurrence rules (RRULE format)\",\n items: { type: \"string\" },\n },\n },\n },\n },\n {\n name: \"create_event\",\n description: \"Create a new calendar event\",\n inputSchema: {\n type: \"object\",\n properties: {\n calendarId: {\n type: \"string\",\n description: \"Calendar ID (defaults to 'primary')\",\n },\n summary: {\n type: \"string\",\n description: \"Event title\",\n },\n description: {\n type: \"string\",\n description: \"Event description\",\n },\n location: {\n type: \"string\",\n description: \"Event location\",\n },\n start: {\n type: \"object\",\n description:\n \"Start time. Use dateTime for timed events (RFC3339) or date for all-day (YYYY-MM-DD)\",\n properties: {\n dateTime: {\n type: \"string\",\n description: \"RFC3339 timestamp (e.g., 2024-01-15T09:00:00-05:00)\",\n },\n date: { type: \"string\", description: \"All-day date (YYYY-MM-DD)\" },\n timeZone: { type: \"string\", description: \"IANA timezone\" },\n },\n },\n end: {\n type: \"object\",\n description: \"End time (same format as start)\",\n properties: {\n dateTime: { type: \"string\" },\n date: { type: \"string\" },\n timeZone: { type: \"string\" },\n },\n },\n attendees: {\n type: \"array\",\n description: \"List of attendee email addresses\",\n items: {\n type: \"object\",\n properties: {\n email: { type: \"string\" },\n displayName: { type: \"string\" },\n optional: { type: \"boolean\" },\n },\n required: [\"email\"],\n },\n },\n addGoogleMeet: {\n type: \"boolean\",\n description: \"Add Google Meet video conference (default: false)\",\n },\n reminders: {\n type: \"array\",\n description: \"Custom reminders (overrides calendar defaults)\",\n items: {\n type: \"object\",\n properties: {\n method: { type: \"string\", enum: [\"email\", \"popup\"] },\n minutes: { type: \"number\", description: \"Minutes before event\" },\n },\n },\n },\n colorId: {\n type: \"string\",\n description: \"Event color ID (1-11)\",\n },\n recurrence: {\n type: \"array\",\n description: \"RRULE strings for recurring events\",\n items: { type: \"string\" },\n },\n sendUpdates: {\n type: \"string\",\n enum: [\"all\", \"externalOnly\", \"none\"],\n description: \"Who to send notifications to (default: all)\",\n },\n },\n required: [\"summary\", \"start\", \"end\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Created event ID\" },\n summary: { type: \"string\", description: \"Event title\" },\n htmlLink: { type: \"string\", description: \"Link to event\" },\n hangoutLink: { type: \"string\", description: \"Google Meet link if created\" },\n },\n },\n },\n {\n name: \"update_event\",\n description: \"Update an existing calendar event\",\n inputSchema: {\n type: \"object\",\n properties: {\n calendarId: {\n type: \"string\",\n description: \"Calendar ID (defaults to 'primary')\",\n },\n eventId: {\n type: \"string\",\n description: \"Event ID to update\",\n },\n summary: { type: \"string\", description: \"New event title\" },\n description: { type: \"string\", description: \"New description\" },\n location: { type: \"string\", description: \"New location\" },\n start: {\n type: \"object\",\n description: \"New start time\",\n properties: {\n dateTime: { type: \"string\" },\n date: { type: \"string\" },\n timeZone: { type: \"string\" },\n },\n },\n end: {\n type: \"object\",\n description: \"New end time\",\n properties: {\n dateTime: { type: \"string\" },\n date: { type: \"string\" },\n timeZone: { type: \"string\" },\n },\n },\n attendees: {\n type: \"array\",\n description: \"Replace attendee list\",\n items: {\n type: \"object\",\n properties: {\n email: { type: \"string\" },\n displayName: { type: \"string\" },\n optional: { type: \"boolean\" },\n },\n },\n },\n addGoogleMeet: {\n type: \"boolean\",\n description: \"Add Google Meet if not present\",\n },\n reminders: {\n type: \"array\",\n description: \"New custom reminders\",\n items: {\n type: \"object\",\n properties: {\n method: { type: \"string\", enum: [\"email\", \"popup\"] },\n minutes: { type: \"number\" },\n },\n },\n },\n colorId: { type: \"string\", description: \"New color ID (1-11)\" },\n sendUpdates: {\n type: \"string\",\n enum: [\"all\", \"externalOnly\", \"none\"],\n description: \"Who to notify of changes\",\n },\n },\n required: [\"eventId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Updated event ID\" },\n summary: { type: \"string\", description: \"Event title\" },\n htmlLink: { type: \"string\", description: \"Link to event\" },\n hangoutLink: { type: \"string\", description: \"Google Meet link\" },\n },\n },\n },\n {\n name: \"delete_event\",\n description: \"Delete a calendar event\",\n inputSchema: {\n type: \"object\",\n properties: {\n calendarId: {\n type: \"string\",\n description: \"Calendar ID (defaults to 'primary')\",\n },\n eventId: {\n type: \"string\",\n description: \"Event ID to delete\",\n },\n sendUpdates: {\n type: \"string\",\n enum: [\"all\", \"externalOnly\", \"none\"],\n description: \"Who to send cancellation notices to (default: all)\",\n },\n },\n required: [\"eventId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n deleted: { type: \"boolean\", description: \"Whether deletion succeeded\" },\n eventId: { type: \"string\", description: \"Deleted event ID\" },\n },\n },\n },\n {\n name: \"find_free_time\",\n description: \"Find free time slots across calendars (max 50 calendars)\",\n inputSchema: {\n type: \"object\",\n properties: {\n calendarIds: {\n type: \"array\",\n description:\n \"Calendar IDs to check (e.g., ['primary', 'user@example.com']). Max 50 calendars.\",\n items: { type: \"string\" },\n },\n timeMin: {\n type: \"string\",\n description: \"Start of search range (RFC3339 timestamp)\",\n },\n timeMax: {\n type: \"string\",\n description: \"End of search range (RFC3339 timestamp)\",\n },\n duration: {\n type: \"number\",\n description: \"Minimum free slot duration in minutes\",\n },\n timeZone: {\n type: \"string\",\n description: \"(optional, default: UTC) Timezone for results\",\n },\n },\n required: [\"calendarIds\", \"timeMin\", \"timeMax\", \"duration\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n freeSlots: {\n type: \"array\",\n description: \"Available time slots\",\n items: {\n type: \"object\",\n properties: {\n start: { type: \"string\", description: \"Slot start (ISO 8601)\" },\n end: { type: \"string\", description: \"Slot end (ISO 8601)\" },\n durationMinutes: { type: \"number\", description: \"Slot duration in minutes\" },\n },\n },\n },\n busyPeriods: {\n type: \"array\",\n description: \"Busy periods found\",\n items: {\n type: \"object\",\n properties: {\n start: { type: \"string\" },\n end: { type: \"string\" },\n },\n },\n },\n },\n },\n },\n];\n\n// Gmail tools\nexport const gmailTools: ToolDefinition[] = [\n // Core Email Operations\n {\n name: \"send_email\",\n description: \"Send an email\",\n inputSchema: {\n type: \"object\",\n properties: {\n to: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Recipient email addresses\",\n },\n subject: { type: \"string\", description: \"Email subject\" },\n body: { type: \"string\", description: \"Plain text email body\" },\n html: { type: \"string\", description: \"HTML email body (optional)\" },\n cc: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"CC recipients\",\n },\n bcc: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"BCC recipients\",\n },\n replyTo: { type: \"string\", description: \"Reply-to address\" },\n attachments: {\n type: \"array\",\n description: \"File attachments\",\n items: {\n type: \"object\",\n properties: {\n filename: { type: \"string\" },\n content: { type: \"string\", description: \"Base64-encoded content\" },\n mimeType: { type: \"string\" },\n },\n required: [\"filename\", \"content\"],\n },\n },\n threadId: { type: \"string\", description: \"Thread ID to reply to\" },\n inReplyTo: { type: \"string\", description: \"Message-ID for threading\" },\n },\n required: [\"to\", \"subject\", \"body\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Sent message ID\" },\n threadId: { type: \"string\", description: \"Thread ID\" },\n labelIds: { type: \"array\", items: { type: \"string\" } },\n },\n },\n },\n {\n name: \"draft_email\",\n description: \"Create a draft email (can be completed later)\",\n inputSchema: {\n type: \"object\",\n properties: {\n to: { type: \"array\", items: { type: \"string\" }, description: \"Recipients\" },\n subject: { type: \"string\", description: \"Subject\" },\n body: { type: \"string\", description: \"Plain text body\" },\n html: { type: \"string\", description: \"HTML body\" },\n cc: { type: \"array\", items: { type: \"string\" } },\n bcc: { type: \"array\", items: { type: \"string\" } },\n replyTo: { type: \"string\" },\n attachments: { type: \"array\" },\n threadId: { type: \"string\" },\n },\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Draft ID\" },\n messageId: { type: \"string\", description: \"Message ID\" },\n threadId: { type: \"string\" },\n },\n },\n },\n {\n name: \"read_email\",\n description: \"Read email content and metadata\",\n inputSchema: {\n type: \"object\",\n properties: {\n messageId: { type: \"string\", description: \"Email message ID\" },\n format: {\n type: \"string\",\n enum: [\"full\", \"metadata\", \"minimal\", \"raw\"],\n description: \"Response format (default: full)\",\n },\n contentFormat: {\n type: \"string\",\n enum: [\"full\", \"text\", \"headers\"],\n description:\n \"Content format: 'full' (default, includes HTML), 'text' (plain text only, smaller), 'headers' (metadata only, no body)\",\n },\n },\n required: [\"messageId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\" },\n threadId: { type: \"string\" },\n labelIds: { type: \"array\", items: { type: \"string\" } },\n headers: {\n type: \"object\",\n description: \"Email headers\",\n properties: {\n from: { type: \"string\", description: \"Sender email address\" },\n to: { type: \"string\", description: \"Recipient(s) email addresses\" },\n cc: { type: \"string\", description: \"CC recipients\" },\n subject: { type: \"string\", description: \"Email subject line\" },\n date: { type: \"string\", description: \"Send date (RFC 2822 format)\" },\n messageId: { type: \"string\", description: \"Email Message-ID header\" },\n },\n },\n body: {\n type: \"object\",\n properties: {\n text: { type: \"string\" },\n html: { type: \"string\" },\n },\n },\n attachments: { type: \"array\" },\n },\n },\n },\n {\n name: \"search_emails\",\n description: \"Search emails using Gmail query syntax (max 500 per request)\",\n inputSchema: {\n type: \"object\",\n properties: {\n query: { type: \"string\", description: \"Gmail search query\" },\n maxResults: {\n type: \"number\",\n description: \"(optional, default: 50) Maximum results (max 500)\",\n },\n pageToken: { type: \"string\", description: \"(optional) Pagination token\" },\n labelIds: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"(optional) Filter by label IDs\",\n },\n includeSpamTrash: {\n type: \"boolean\",\n description: \"(optional, default: false) Include spam and trash\",\n },\n },\n required: [\"query\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n messages: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n id: { type: \"string\" },\n threadId: { type: \"string\" },\n from: { type: \"string\" },\n subject: { type: \"string\" },\n date: { type: \"string\" },\n snippet: { type: \"string\" },\n },\n },\n },\n nextPageToken: { type: \"string\" },\n resultSizeEstimate: { type: \"number\" },\n },\n },\n },\n {\n name: \"delete_email\",\n description: \"Delete emails permanently (max 1000 IDs per request)\",\n inputSchema: {\n type: \"object\",\n properties: {\n messageId: {\n oneOf: [{ type: \"string\" }, { type: \"array\", items: { type: \"string\" }, maxItems: 1000 }],\n description: \"Message ID or array of IDs (max 1000)\",\n },\n },\n required: [\"messageId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n deleted: { type: \"number\", description: \"Number of messages deleted\" },\n messageIds: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"IDs of deleted messages\",\n },\n },\n },\n },\n {\n name: \"modify_email\",\n description: \"Add/remove labels (max 1000 IDs per request)\",\n inputSchema: {\n type: \"object\",\n properties: {\n messageId: {\n oneOf: [{ type: \"string\" }, { type: \"array\", items: { type: \"string\" }, maxItems: 1000 }],\n description: \"Message ID or array of IDs (max 1000)\",\n },\n addLabelIds: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"(optional) Label IDs to add\",\n },\n removeLabelIds: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"(optional) Label IDs to remove\",\n },\n },\n required: [\"messageId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n modified: { type: \"number\", description: \"Number of messages modified\" },\n addedLabels: { type: \"array\", items: { type: \"string\" }, description: \"Labels added\" },\n removedLabels: { type: \"array\", items: { type: \"string\" }, description: \"Labels removed\" },\n },\n },\n },\n {\n name: \"download_attachment\",\n description: \"Download an email attachment to disk\",\n inputSchema: {\n type: \"object\",\n properties: {\n messageId: { type: \"string\", description: \"Email message ID\" },\n attachmentId: { type: \"string\", description: \"Attachment ID from readEmail\" },\n filename: { type: \"string\", description: \"Save filename (optional)\" },\n outputPath: { type: \"string\", description: \"Output directory (optional)\" },\n },\n required: [\"messageId\", \"attachmentId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n path: { type: \"string\", description: \"Saved file path\" },\n size: { type: \"number\", description: \"File size in bytes\" },\n },\n },\n },\n // Label Management\n {\n name: \"update_label\",\n description: \"Update an existing Gmail label\",\n inputSchema: {\n type: \"object\",\n properties: {\n labelId: { type: \"string\", description: \"Label ID to update\" },\n name: { type: \"string\", description: \"(optional) New name\" },\n messageListVisibility: {\n type: \"string\",\n enum: [\"show\", \"hide\"],\n description: \"(optional) Show/hide in message list\",\n },\n labelListVisibility: {\n type: \"string\",\n enum: [\"labelShow\", \"labelShowIfUnread\", \"labelHide\"],\n description: \"(optional) Label list visibility\",\n },\n backgroundColor: { type: \"string\", description: \"(optional) Background color\" },\n textColor: { type: \"string\", description: \"(optional) Text color\" },\n },\n required: [\"labelId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Label ID\" },\n name: { type: \"string\", description: \"Label name\" },\n updated: { type: \"boolean\", description: \"Whether the update succeeded\" },\n },\n },\n },\n {\n name: \"delete_label\",\n description: \"Delete a user-created label\",\n inputSchema: {\n type: \"object\",\n properties: {\n labelId: { type: \"string\", description: \"Label ID to delete\" },\n },\n required: [\"labelId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n deleted: { type: \"boolean\", description: \"Whether the deletion succeeded\" },\n labelId: { type: \"string\", description: \"Deleted label ID\" },\n },\n },\n },\n {\n name: \"list_labels\",\n description: \"List all Gmail labels (system and user-created)\",\n inputSchema: {\n type: \"object\",\n properties: {\n includeSystemLabels: {\n type: \"boolean\",\n description: \"Include INBOX, SENT, etc. (default: true)\",\n },\n },\n },\n outputSchema: {\n type: \"object\",\n properties: {\n labels: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n id: { type: \"string\" },\n name: { type: \"string\" },\n type: { type: \"string\" },\n messagesTotal: { type: \"number\" },\n messagesUnread: { type: \"number\" },\n },\n },\n },\n },\n },\n },\n {\n name: \"get_or_create_label\",\n description: \"Get or create a Gmail label\",\n inputSchema: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"Label name\" },\n messageListVisibility: { type: \"string\", enum: [\"show\", \"hide\"] },\n labelListVisibility: {\n type: \"string\",\n enum: [\"labelShow\", \"labelShowIfUnread\", \"labelHide\"],\n },\n backgroundColor: { type: \"string\" },\n textColor: { type: \"string\" },\n },\n required: [\"name\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\" },\n name: { type: \"string\" },\n created: { type: \"boolean\", description: \"True if newly created\" },\n },\n },\n },\n // Filter Management\n {\n name: \"create_filter\",\n description: \"Create an email filter\",\n inputSchema: {\n type: \"object\",\n properties: {\n // Direct mode\n criteria: {\n type: \"object\",\n description: \"Filter criteria (direct mode)\",\n properties: {\n from: { type: \"string\" },\n to: { type: \"string\" },\n subject: { type: \"string\" },\n query: { type: \"string\" },\n hasAttachment: { type: \"boolean\" },\n excludeChats: { type: \"boolean\" },\n size: { type: \"number\" },\n sizeComparison: { type: \"string\", enum: [\"larger\", \"smaller\"] },\n },\n },\n action: {\n type: \"object\",\n description: \"Actions (direct mode)\",\n properties: {\n addLabelIds: { type: \"array\", items: { type: \"string\" } },\n removeLabelIds: { type: \"array\", items: { type: \"string\" } },\n forward: { type: \"string\" },\n },\n },\n // Template mode\n template: {\n type: \"string\",\n enum: [\"fromSender\", \"withSubject\", \"withAttachments\", \"largeEmails\", \"mailingList\"],\n description: \"Use pre-built template instead of criteria/action\",\n },\n labelIds: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Labels (template mode)\",\n },\n archive: { type: \"boolean\", description: \"Archive matching emails (template mode)\" },\n email: { type: \"string\", description: \"Email for fromSender/mailingList template\" },\n subject: { type: \"string\", description: \"Subject for withSubject template\" },\n sizeBytes: { type: \"number\", description: \"Size for largeEmails template\" },\n listAddress: { type: \"string\", description: \"List address for mailingList template\" },\n },\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\" },\n template: { type: \"string\" },\n criteria: { type: \"object\" },\n action: { type: \"object\" },\n },\n },\n },\n {\n name: \"list_filters\",\n description: \"List filters or get specific filter details\",\n inputSchema: {\n type: \"object\",\n properties: {\n filterId: { type: \"string\", description: \"Optional: get specific filter\" },\n },\n },\n outputSchema: {\n type: \"object\",\n properties: {\n filters: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n id: { type: \"string\" },\n criteria: { type: \"object\" },\n action: { type: \"object\" },\n },\n },\n },\n },\n },\n },\n {\n name: \"delete_filter\",\n description: \"Delete an email filter\",\n inputSchema: {\n type: \"object\",\n properties: {\n filterId: { type: \"string\", description: \"Filter ID to delete\" },\n },\n required: [\"filterId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n deleted: { type: \"boolean\", description: \"Whether the deletion succeeded\" },\n filterId: { type: \"string\", description: \"Deleted filter ID\" },\n },\n },\n },\n];\n\nimport { isServiceEnabled, areUnifiedToolsEnabled, type ServiceName } from \"../config/index.js\";\n\n/** Map of service names to their tool definitions */\nexport const SERVICE_TOOL_MAP: Record<ServiceName, ToolDefinition[]> = {\n drive: driveTools,\n docs: docsTools,\n sheets: sheetsTools,\n slides: slidesTools,\n calendar: calendarTools,\n gmail: gmailTools,\n};\n\n/** Discovery tool for listing available tools */\nexport const discoveryTools: ToolDefinition[] = [\n {\n name: \"list_tools\",\n description: \"List available tools, optionally filtered by service or keyword\",\n inputSchema: {\n type: \"object\",\n properties: {\n service: {\n type: \"string\",\n enum: [\"drive\", \"docs\", \"sheets\", \"slides\", \"calendar\", \"gmail\", \"unified\"],\n description: \"(optional) Filter by service name\",\n },\n keyword: {\n type: \"string\",\n description: \"(optional) Filter by keyword in tool name or description\",\n },\n includeSchemas: {\n type: \"boolean\",\n description: \"(optional, default: false) Include full input/output schemas in response\",\n },\n },\n },\n outputSchema: {\n type: \"object\",\n properties: {\n tools: {\n type: \"array\",\n description: \"List of matching tools\",\n items: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"Tool name\" },\n description: { type: \"string\", description: \"Tool description\" },\n service: { type: \"string\", description: \"Service the tool belongs to\" },\n inputSchema: {\n type: \"object\",\n description: \"Input schema (if includeSchemas=true)\",\n },\n outputSchema: {\n type: \"object\",\n description: \"Output schema (if includeSchemas=true)\",\n },\n },\n },\n },\n totalCount: { type: \"number\", description: \"Total number of matching tools\" },\n services: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Available services\",\n },\n },\n },\n },\n];\n\n/**\n * Get all tool definitions combined into a single array.\n * Filters by enabled services (GOOGLE_WORKSPACE_SERVICES env var).\n * If not set, all services are enabled (backward compatible).\n */\nexport function getAllTools(): ToolDefinition[] {\n const tools: ToolDefinition[] = [];\n\n // Always include discovery tools\n tools.push(...discoveryTools);\n\n for (const [service, serviceTools] of Object.entries(SERVICE_TOOL_MAP)) {\n if (isServiceEnabled(service as ServiceName)) {\n tools.push(...serviceTools);\n }\n }\n\n // Unified tools require drive+docs+sheets+slides to all be enabled\n if (areUnifiedToolsEnabled()) {\n tools.push(...unifiedTools);\n }\n\n return tools;\n}\n", "/**\n * MCP Prompt definitions for common Google Drive workflows\n */\n\nexport interface PromptDefinition {\n name: string;\n description: string;\n arguments?: Array<{\n name: string;\n description: string;\n required?: boolean;\n }>;\n}\n\nexport interface PromptMessage {\n role: \"user\" | \"assistant\";\n content: {\n type: \"text\";\n text: string;\n };\n}\n\nexport const PROMPTS: PromptDefinition[] = [\n {\n name: \"organize-folder\",\n description:\n \"Organize files in a folder by type or date. Creates subfolders and moves files accordingly.\",\n arguments: [\n {\n name: \"folderId\",\n description: 'The ID of the folder to organize (use \"root\" for My Drive)',\n required: true,\n },\n {\n name: \"organizeBy\",\n description: 'How to organize: \"type\" (by file type) or \"date\" (by creation date)',\n required: true,\n },\n ],\n },\n {\n name: \"backup-folder\",\n description:\n \"Export all files in a folder to a local directory. Google Docs are exported as their native formats.\",\n arguments: [\n {\n name: \"folderId\",\n description: \"The ID of the folder to backup\",\n required: true,\n },\n {\n name: \"localPath\",\n description: \"Local directory path to save the backup\",\n required: true,\n },\n ],\n },\n {\n name: \"share-with-team\",\n description: \"Share multiple files with a list of email addresses with specified permissions.\",\n arguments: [\n {\n name: \"fileIds\",\n description: \"Comma-separated list of file IDs to share\",\n required: true,\n },\n {\n name: \"emails\",\n description: \"Comma-separated list of email addresses\",\n required: true,\n },\n {\n name: \"role\",\n description: \"Permission role: reader, commenter, or writer\",\n required: false,\n },\n ],\n },\n {\n name: \"cleanup-old-files\",\n description: \"Find and optionally delete files older than a specified number of days.\",\n arguments: [\n {\n name: \"folderId\",\n description: 'The folder to search (use \"root\" for My Drive, or omit for all files)',\n required: false,\n },\n {\n name: \"daysOld\",\n description: \"Minimum age in days for files to be considered old\",\n required: true,\n },\n {\n name: \"action\",\n description: 'Action to take: \"list\" (just show files) or \"trash\" (move to trash)',\n required: false,\n },\n ],\n },\n {\n name: \"migrate-format\",\n description:\n \"Convert legacy Microsoft Office files (.doc, .xls, .ppt) to Google Workspace formats.\",\n arguments: [\n {\n name: \"folderId\",\n description: 'The folder to search for files to convert (use \"root\" for My Drive)',\n required: false,\n },\n {\n name: \"fileTypes\",\n description:\n 'Comma-separated file types to convert: doc, xls, ppt (or \"all\" for all types)',\n required: false,\n },\n ],\n },\n];\n\n/**\n * Generate prompt messages for a given prompt name and arguments\n */\nexport function generatePromptMessages(\n promptName: string,\n args: Record<string, string>,\n): PromptMessage[] {\n switch (promptName) {\n case \"organize-folder\":\n return generateOrganizeFolderPrompt(args);\n case \"backup-folder\":\n return generateBackupFolderPrompt(args);\n case \"share-with-team\":\n return generateShareWithTeamPrompt(args);\n case \"cleanup-old-files\":\n return generateCleanupOldFilesPrompt(args);\n case \"migrate-format\":\n return generateMigrateFormatPrompt(args);\n default:\n throw new Error(`Unknown prompt: ${promptName}`);\n }\n}\n\nfunction generateOrganizeFolderPrompt(args: Record<string, string>): PromptMessage[] {\n const folderId = args.folderId || \"root\";\n const organizeBy = args.organizeBy || \"type\";\n\n const instructions =\n organizeBy === \"type\"\n ? `Please organize the files in folder \"${folderId}\" by their file type:\n\n1. First, use listFolder to get all files in the folder\n2. Create subfolders for each file type found (e.g., \"Documents\", \"Spreadsheets\", \"Images\", \"Videos\", \"Other\")\n3. Move each file to its appropriate subfolder using moveItem\n4. Report the results showing how many files were moved to each category\n\nFile type mappings:\n- Documents: .doc, .docx, .pdf, .txt, Google Docs\n- Spreadsheets: .xls, .xlsx, .csv, Google Sheets\n- Presentations: .ppt, .pptx, Google Slides\n- Images: .jpg, .jpeg, .png, .gif, .svg\n- Videos: .mp4, .mov, .avi\n- Audio: .mp3, .wav\n- Other: everything else`\n : `Please organize the files in folder \"${folderId}\" by their creation date:\n\n1. First, use listFolder to get all files in the folder\n2. For each file, check its creation date using getFileMetadata\n3. Create subfolders by year and month (e.g., \"2024/January\", \"2024/February\")\n4. Move each file to its appropriate date-based subfolder using moveItem\n5. Report the results showing how many files were organized`;\n\n return [\n {\n role: \"user\",\n content: {\n type: \"text\",\n text: instructions,\n },\n },\n ];\n}\n\nfunction generateBackupFolderPrompt(args: Record<string, string>): PromptMessage[] {\n const folderId = args.folderId;\n const localPath = args.localPath;\n\n return [\n {\n role: \"user\",\n content: {\n type: \"text\",\n text: `Please backup all files from Google Drive folder \"${folderId}\" to the local directory \"${localPath}\":\n\n1. Use listFolder to get all files in the folder (including subfolders recursively)\n2. For each file:\n - For Google Docs: export as .docx using exportFile\n - For Google Sheets: export as .xlsx using exportFile\n - For Google Slides: export as .pptx using exportFile\n - For other files: download using downloadFile\n3. Preserve the folder structure in the local directory\n4. Report progress and any errors encountered\n5. At the end, provide a summary of:\n - Total files backed up\n - Total size\n - Any files that failed to backup`,\n },\n },\n ];\n}\n\nfunction generateShareWithTeamPrompt(args: Record<string, string>): PromptMessage[] {\n const fileIds = args.fileIds;\n const emails = args.emails;\n const role = args.role || \"reader\";\n\n return [\n {\n role: \"user\",\n content: {\n type: \"text\",\n text: `Please share the following files with the team:\n\nFiles to share: ${fileIds}\nTeam members: ${emails}\nPermission level: ${role}\n\nSteps:\n1. For each file ID in the list, use shareFile to share with each email address\n2. Use role \"${role}\" for all shares\n3. Report the results showing:\n - Which files were successfully shared\n - Which email addresses received access\n - Any errors or files that couldn't be shared\n\nNote: If any file is already shared with a user, you may need to update their permission level.`,\n },\n },\n ];\n}\n\nfunction generateCleanupOldFilesPrompt(args: Record<string, string>): PromptMessage[] {\n const folderId = args.folderId || \"\";\n const daysOld = args.daysOld;\n const action = args.action || \"list\";\n\n const folderClause = folderId ? `in folder \"${folderId}\"` : \"across your entire Google Drive\";\n\n const actionInstructions =\n action === \"trash\"\n ? `4. For each file older than ${daysOld} days, use deleteItem to move it to trash\n5. Report the files that were trashed`\n : `4. Do NOT delete any files - only report what was found`;\n\n return [\n {\n role: \"user\",\n content: {\n type: \"text\",\n text: `Please find files ${folderClause} that are older than ${daysOld} days:\n\n1. Use search to find files with modifiedTime older than ${daysOld} days ago\n2. For each file found, get its metadata to show name, size, and last modified date\n3. Sort results by date (oldest first)\n${actionInstructions}\n\nReport format:\n- File name\n- Size\n- Last modified date\n- Location (parent folder)\n\nTotal count and size of old files found.`,\n },\n },\n ];\n}\n\nfunction generateMigrateFormatPrompt(args: Record<string, string>): PromptMessage[] {\n const folderId = args.folderId || \"root\";\n const fileTypes = args.fileTypes || \"all\";\n\n const typeFilter =\n fileTypes === \"all\"\n ? \"Microsoft Office files (.doc, .docx, .xls, .xlsx, .ppt, .pptx)\"\n : fileTypes\n .split(\",\")\n .map((t) => `.${t.trim()}`)\n .join(\", \");\n\n return [\n {\n role: \"user\",\n content: {\n type: \"text\",\n text: `Please find and convert legacy Office files to Google Workspace formats in folder \"${folderId}\":\n\nTarget file types: ${typeFilter}\n\nSteps:\n1. Use search to find files matching the target types in the specified folder\n2. For each file found, report:\n - Current file name and type\n - File size\n - Last modified date\n3. Ask for confirmation before proceeding with conversion\n4. To convert a file:\n - Upload it with convert=true option to create a Google Docs/Sheets/Slides version\n - The original file will remain (user can delete it later if desired)\n5. Report conversion results:\n - Successfully converted files\n - Any files that failed to convert\n - Total storage impact (Google Workspace files don't count against quota)\n\nNote: This creates NEW Google Workspace files alongside the originals. Original files are preserved.`,\n },\n },\n ];\n}\n", "import type { drive_v3 } from \"googleapis\";\nimport {\n log,\n successResponse,\n structuredResponse,\n errorResponse,\n withTimeout,\n withRetry,\n elicitFileSelection,\n elicitConfirmation,\n formatDisambiguationOptions,\n validateArgs,\n} from \"../utils/index.js\";\nimport type { ToolResponse } from \"../utils/index.js\";\nimport {\n escapeQueryString,\n combineQueries,\n buildFullTextQuery,\n buildNameQuery,\n} from \"../utils/gdrive-query.js\";\nimport { formatBytes, formatBytesCompact } from \"../utils/format.js\";\nimport {\n GetFolderTreeSchema,\n SearchSchema,\n CreateTextFileSchema,\n UpdateTextFileSchema,\n CreateFolderSchema,\n ListFolderSchema,\n DeleteItemSchema,\n RenameItemSchema,\n MoveItemSchema,\n CopyFileSchema,\n GetFileMetadataSchema,\n ExportFileSchema,\n ShareFileSchema,\n GetSharingSchema,\n ListRevisionsSchema,\n RestoreRevisionSchema,\n DownloadFileSchema,\n UploadFileSchema,\n GetStorageQuotaSchema,\n StarFileSchema,\n ResolveFilePathSchema,\n BatchDeleteSchema,\n BatchRestoreSchema,\n BatchMoveSchema,\n BatchShareSchema,\n RemovePermissionSchema,\n ListTrashSchema,\n RestoreFromTrashSchema,\n EmptyTrashSchema,\n} from \"../schemas/index.js\";\nimport {\n FOLDER_MIME_TYPE,\n TEXT_MIME_TYPES,\n getMimeTypeFromFilename,\n validateTextFileExtension,\n resolveFolderId,\n resolveOptionalFolderPath,\n checkFileExists,\n processBatchOperation,\n} from \"./helpers.js\";\nimport type { HandlerContext } from \"./helpers.js\";\n\nexport async function handleSearch(drive: drive_v3.Drive, args: unknown): Promise<ToolResponse> {\n const validation = validateArgs(SearchSchema, args);\n if (!validation.success) return validation.response;\n const { query: userQuery, searchType, pageSize, pageToken } = validation.data;\n\n // Build base query based on searchType\n let baseQuery: string;\n switch (searchType) {\n case \"name_exact\":\n baseQuery = buildNameQuery(userQuery, true); // name = 'query'\n break;\n case \"name\":\n baseQuery = buildNameQuery(userQuery, false); // name contains 'query'\n break;\n default:\n baseQuery = buildFullTextQuery(userQuery); // fullText contains 'query'\n }\n const formattedQuery = combineQueries(baseQuery, \"trashed = false\");\n\n const res = await drive.files.list({\n q: formattedQuery,\n pageSize: Math.min(pageSize || 50, 100),\n pageToken: pageToken,\n fields: \"nextPageToken, files(id, name, mimeType, modifiedTime, size)\",\n includeItemsFromAllDrives: true,\n supportsAllDrives: true,\n });\n\n const fileList =\n res.data.files?.map((f: drive_v3.Schema$File) => `${f.name} (${f.mimeType})`).join(\"\\n\") || \"\";\n log(\"Search results\", {\n query: userQuery,\n resultCount: res.data.files?.length,\n });\n\n let response = `Found ${res.data.files?.length ?? 0} files:\\n${fileList}`;\n if (res.data.nextPageToken) {\n response += `\\n\\nMore results available. Use pageToken: ${res.data.nextPageToken}`;\n }\n\n return successResponse(response);\n}\n\nexport async function handleCreateTextFile(\n drive: drive_v3.Drive,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(CreateTextFileSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n validateTextFileExtension(data.name);\n const parentFolderId = await resolveOptionalFolderPath(\n drive,\n data.parentFolderId,\n data.parentPath,\n );\n\n // Check if file already exists\n const existingFileId = await checkFileExists(drive, data.name, parentFolderId);\n if (existingFileId) {\n return errorResponse(\n `A file named \"${data.name}\" already exists in this location. ` +\n `To update it, use updateTextFile with fileId: ${existingFileId}`,\n );\n }\n\n const fileMetadata = {\n name: data.name,\n mimeType: getMimeTypeFromFilename(data.name),\n parents: [parentFolderId],\n };\n\n log(\"About to create file\", { driveExists: !!drive });\n\n const file = await drive.files.create({\n requestBody: fileMetadata,\n media: {\n mimeType: fileMetadata.mimeType,\n body: data.content,\n },\n supportsAllDrives: true,\n });\n\n log(\"File created successfully\", { fileId: file.data?.id });\n return successResponse(\n `Created file: ${file.data?.name || data.name}\\nID: ${file.data?.id || \"unknown\"}`,\n );\n}\n\nexport async function handleUpdateTextFile(\n drive: drive_v3.Drive,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(UpdateTextFileSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Check file MIME type\n const existingFile = await drive.files.get({\n fileId: data.fileId,\n fields: \"mimeType, name, parents\",\n supportsAllDrives: true,\n });\n\n const currentMimeType = existingFile.data.mimeType || \"text/plain\";\n if (!Object.values(TEXT_MIME_TYPES).includes(currentMimeType)) {\n return errorResponse(\n `File \"${existingFile.data.name}\" (${data.fileId}) is not a text or markdown file. ` +\n `Current type: ${currentMimeType}. Supported types: text/plain, text/markdown.`,\n );\n }\n\n const updateMetadata: { name?: string; mimeType?: string } = {};\n if (data.name) {\n validateTextFileExtension(data.name);\n updateMetadata.name = data.name;\n updateMetadata.mimeType = getMimeTypeFromFilename(data.name);\n }\n\n const updatedFile = await drive.files.update({\n fileId: data.fileId,\n requestBody: updateMetadata,\n media: {\n mimeType: updateMetadata.mimeType || currentMimeType,\n body: data.content,\n },\n fields: \"id, name, modifiedTime, webViewLink\",\n supportsAllDrives: true,\n });\n\n return successResponse(\n `Updated file: ${updatedFile.data.name}\\nModified: ${updatedFile.data.modifiedTime}`,\n );\n}\n\nexport async function handleCreateFolder(\n drive: drive_v3.Drive,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(CreateFolderSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n const parentFolderId = await resolveOptionalFolderPath(drive, data.parent, data.parentPath);\n\n // Check if folder already exists\n const existingFolderId = await checkFileExists(drive, data.name, parentFolderId);\n if (existingFolderId) {\n return errorResponse(\n `A folder named \"${data.name}\" already exists in this location. ` +\n `Folder ID: ${existingFolderId}`,\n );\n }\n\n const folderMetadata = {\n name: data.name,\n mimeType: FOLDER_MIME_TYPE,\n parents: [parentFolderId],\n };\n\n const folder = await drive.files.create({\n requestBody: folderMetadata,\n fields: \"id, name, webViewLink\",\n supportsAllDrives: true,\n });\n\n log(\"Folder created successfully\", {\n folderId: folder.data.id,\n name: folder.data.name,\n });\n\n return successResponse(`Created folder: ${folder.data.name}\\nID: ${folder.data.id}`);\n}\n\nexport async function handleListFolder(\n drive: drive_v3.Drive,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(ListFolderSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Default to root if no folder specified\n const targetFolderId = data.folderId || \"root\";\n\n try {\n const res = await drive.files.list({\n q: `'${targetFolderId}' in parents and trashed = false`,\n pageSize: Math.min(data.pageSize || 50, 100),\n pageToken: data.pageToken,\n fields: \"nextPageToken, files(id, name, mimeType, modifiedTime, size)\",\n orderBy: \"name\",\n includeItemsFromAllDrives: true,\n supportsAllDrives: true,\n });\n\n const files = res.data.files || [];\n const formattedFiles = files\n .map((file: drive_v3.Schema$File) => {\n const isFolder = file.mimeType === FOLDER_MIME_TYPE;\n return `${isFolder ? \"\uD83D\uDCC1\" : \"\uD83D\uDCC4\"} ${file.name} (ID: ${file.id})`;\n })\n .join(\"\\n\");\n\n let response = `Contents of folder:\\n\\n${formattedFiles}`;\n if (res.data.nextPageToken) {\n response += `\\n\\nMore items available. Use pageToken: ${res.data.nextPageToken}`;\n }\n\n return successResponse(response);\n } catch (error) {\n // Handle 404 error with clearer message including folder ID\n if (error instanceof Error && error.message.includes(\"not found\")) {\n return errorResponse(`Folder not found: ${targetFolderId}`, { code: \"NOT_FOUND\" });\n }\n throw error;\n }\n}\n\nexport async function handleDeleteItem(\n drive: drive_v3.Drive,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(DeleteItemSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n const item = await drive.files.get({\n fileId: data.itemId,\n fields: \"name, mimeType\",\n supportsAllDrives: true,\n });\n\n // If it's a folder, count its contents before deleting\n let countInfo = \"\";\n if (item.data.mimeType === FOLDER_MIME_TYPE) {\n const contents = await drive.files.list({\n q: `'${data.itemId}' in parents and trashed = false`,\n fields: \"files(id, mimeType)\",\n pageSize: 1000,\n supportsAllDrives: true,\n includeItemsFromAllDrives: true,\n });\n\n const files = contents.data.files || [];\n const fileCount = files.filter((f) => f.mimeType !== FOLDER_MIME_TYPE).length;\n const folderCount = files.filter((f) => f.mimeType === FOLDER_MIME_TYPE).length;\n\n if (fileCount > 0 || folderCount > 0) {\n const parts: string[] = [];\n if (fileCount > 0) parts.push(`${fileCount} file${fileCount !== 1 ? \"s\" : \"\"}`);\n if (folderCount > 0) parts.push(`${folderCount} subfolder${folderCount !== 1 ? \"s\" : \"\"}`);\n countInfo = ` (contains ${parts.join(\", \")})`;\n }\n }\n\n // Move to trash instead of permanent deletion\n await drive.files.update({\n fileId: data.itemId,\n requestBody: { trashed: true },\n supportsAllDrives: true,\n });\n\n log(\"Item moved to trash successfully\", {\n itemId: data.itemId,\n name: item.data.name,\n });\n return successResponse(`Moved \"${item.data.name}\" to trash${countInfo}`);\n}\n\nexport async function handleRenameItem(\n drive: drive_v3.Drive,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(RenameItemSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // If it's a text file, check extension\n const item = await drive.files.get({\n fileId: data.itemId,\n fields: \"name, mimeType\",\n supportsAllDrives: true,\n });\n\n if (Object.values(TEXT_MIME_TYPES).includes(item.data.mimeType || \"\")) {\n validateTextFileExtension(data.newName);\n }\n\n const updatedItem = await drive.files.update({\n fileId: data.itemId,\n requestBody: { name: data.newName },\n fields: \"id, name, modifiedTime\",\n supportsAllDrives: true,\n });\n\n return successResponse(`Successfully renamed \"${item.data.name}\" to \"${updatedItem.data.name}\"`);\n}\n\nexport async function handleMoveItem(drive: drive_v3.Drive, args: unknown): Promise<ToolResponse> {\n const validation = validateArgs(MoveItemSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n const destinationFolderId = await resolveOptionalFolderPath(\n drive,\n data.destinationFolderId,\n data.destinationPath,\n );\n\n // Check we aren't moving a folder into itself\n if (destinationFolderId === data.itemId) {\n return errorResponse(\"Cannot move a folder into itself.\");\n }\n\n const item = await drive.files.get({\n fileId: data.itemId,\n fields: \"name, parents\",\n supportsAllDrives: true,\n });\n\n // Perform move\n await drive.files.update({\n fileId: data.itemId,\n addParents: destinationFolderId,\n removeParents: item.data.parents?.join(\",\") || \"\",\n fields: \"id, name, parents\",\n supportsAllDrives: true,\n });\n\n // Get the destination folder name for a nice response\n const destinationFolder = await drive.files.get({\n fileId: destinationFolderId,\n fields: \"name\",\n supportsAllDrives: true,\n });\n\n return successResponse(\n `Successfully moved \"${item.data.name}\" to \"${destinationFolder.data.name}\"`,\n );\n}\n\nexport async function handleCopyFile(drive: drive_v3.Drive, args: unknown): Promise<ToolResponse> {\n const validation = validateArgs(CopyFileSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Get source file metadata\n const sourceFile = await drive.files.get({\n fileId: data.sourceFileId,\n fields: \"name, parents\",\n supportsAllDrives: true,\n });\n\n const destinationName = data.destinationName || `Copy of ${sourceFile.data.name}`;\n const destinationFolderId = data.destinationFolderId\n ? await resolveFolderId(drive, data.destinationFolderId)\n : sourceFile.data.parents?.[0] || \"root\";\n\n // Check if destination name already exists\n const existingFileId = await checkFileExists(drive, destinationName, destinationFolderId);\n if (existingFileId) {\n return errorResponse(\n `A file named \"${destinationName}\" already exists in the destination folder. ` +\n `Existing file ID: ${existingFileId}`,\n );\n }\n\n // Copy the file\n const copiedFile = await drive.files.copy({\n fileId: data.sourceFileId,\n requestBody: {\n name: destinationName,\n parents: [destinationFolderId],\n },\n fields: \"id, name, webViewLink\",\n supportsAllDrives: true,\n });\n\n log(\"File copied successfully\", {\n sourceId: data.sourceFileId,\n newId: copiedFile.data.id,\n });\n\n return successResponse(\n `Copied file: ${copiedFile.data.name}\\nNew ID: ${copiedFile.data.id}\\nLink: ${copiedFile.data.webViewLink}`,\n );\n}\n\nexport async function handleGetFileMetadata(\n drive: drive_v3.Drive,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(GetFileMetadataSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n const file = await withTimeout(\n drive.files.get({\n fileId: data.fileId,\n fields:\n \"id, name, mimeType, size, createdTime, modifiedTime, owners, shared, webViewLink, parents, description, starred\",\n supportsAllDrives: true,\n }),\n 30000,\n \"Get file metadata\",\n );\n\n const metadata = file.data;\n const ownerNames =\n metadata.owners?.map((o) => o.displayName || o.emailAddress).join(\", \") || \"Unknown\";\n const sizeStr = formatBytes(metadata.size);\n\n const textResponse = [\n `Name: ${metadata.name}`,\n `ID: ${metadata.id}`,\n `Type: ${metadata.mimeType}`,\n `Size: ${sizeStr}`,\n `Created: ${metadata.createdTime}`,\n `Modified: ${metadata.modifiedTime}`,\n `Owner(s): ${ownerNames}`,\n `Shared: ${metadata.shared ? \"Yes\" : \"No\"}`,\n `Starred: ${metadata.starred ? \"Yes\" : \"No\"}`,\n metadata.description ? `Description: ${metadata.description}` : null,\n metadata.parents ? `Parent folder(s): ${metadata.parents.join(\", \")}` : null,\n `Link: ${metadata.webViewLink}`,\n ]\n .filter(Boolean)\n .join(\"\\n\");\n\n return structuredResponse(textResponse, {\n id: metadata.id,\n name: metadata.name,\n mimeType: metadata.mimeType,\n size: metadata.size,\n createdTime: metadata.createdTime,\n modifiedTime: metadata.modifiedTime,\n owners: metadata.owners?.map((o) => ({\n displayName: o.displayName,\n emailAddress: o.emailAddress,\n })),\n shared: metadata.shared,\n starred: metadata.starred,\n description: metadata.description,\n webViewLink: metadata.webViewLink,\n parents: metadata.parents,\n });\n}\n\nconst EXPORT_MIME_TYPES: Record<string, string> = {\n pdf: \"application/pdf\",\n docx: \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n xlsx: \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n pptx: \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\n csv: \"text/csv\",\n tsv: \"text/tab-separated-values\",\n odt: \"application/vnd.oasis.opendocument.text\",\n ods: \"application/vnd.oasis.opendocument.spreadsheet\",\n odp: \"application/vnd.oasis.opendocument.presentation\",\n};\n\nconst GOOGLE_DOC_FORMATS = [\"pdf\", \"docx\", \"odt\"];\nconst GOOGLE_SHEET_FORMATS = [\"pdf\", \"xlsx\", \"csv\", \"tsv\", \"ods\"];\nconst GOOGLE_SLIDES_FORMATS = [\"pdf\", \"pptx\", \"odp\"];\n\nexport async function handleExportFile(\n drive: drive_v3.Drive,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(ExportFileSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Get file metadata to determine type\n const file = await drive.files.get({\n fileId: data.fileId,\n fields: \"name, mimeType\",\n supportsAllDrives: true,\n });\n\n const mimeType = file.data.mimeType || \"\";\n const fileName = file.data.name || \"export\";\n\n // Validate format is compatible with file type\n let validFormats: string[];\n if (mimeType === \"application/vnd.google-apps.document\") {\n validFormats = GOOGLE_DOC_FORMATS;\n } else if (mimeType === \"application/vnd.google-apps.spreadsheet\") {\n validFormats = GOOGLE_SHEET_FORMATS;\n } else if (mimeType === \"application/vnd.google-apps.presentation\") {\n validFormats = GOOGLE_SLIDES_FORMATS;\n } else {\n return errorResponse(\n `File \"${fileName}\" is not a Google Doc, Sheet, or Slides. ` +\n `Cannot export ${mimeType} files. Use this tool only for Google Workspace files.`,\n );\n }\n\n if (!validFormats.includes(data.format)) {\n return errorResponse(\n `Cannot export Google ${mimeType.split(\".\").pop()} to ${data.format}. ` +\n `Valid formats: ${validFormats.join(\", \")}`,\n );\n }\n\n const exportMimeType = EXPORT_MIME_TYPES[data.format];\n\n // Export the file\n const response = await drive.files.export(\n { fileId: data.fileId, mimeType: exportMimeType },\n { responseType: \"arraybuffer\" },\n );\n\n const buffer = Buffer.from(response.data as ArrayBuffer);\n\n // If outputPath is provided, save to file\n if (data.outputPath) {\n const fs = await import(\"fs/promises\");\n const path = await import(\"path\");\n\n const outputFileName = `${fileName}.${data.format}`;\n const fullPath = path.join(data.outputPath, outputFileName);\n\n await fs.writeFile(fullPath, buffer);\n\n log(\"File exported successfully\", {\n fileId: data.fileId,\n outputPath: fullPath,\n });\n return successResponse(`Exported \"${fileName}\" to: ${fullPath}`);\n }\n\n // Otherwise return base64-encoded content\n const base64Content = buffer.toString(\"base64\");\n\n log(\"File exported successfully\", {\n fileId: data.fileId,\n format: data.format,\n });\n return successResponse(\n `Exported \"${fileName}\" as ${data.format}\\n\\n` +\n `Base64 content (${buffer.length} bytes):\\n${base64Content}`,\n );\n}\n\n// -----------------------------------------------------------------------------\n// SHARING HANDLERS\n// -----------------------------------------------------------------------------\n\nexport async function handleShareFile(drive: drive_v3.Drive, args: unknown): Promise<ToolResponse> {\n const validation = validateArgs(ShareFileSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Validate emailAddress required for user/group\n if ((data.type === \"user\" || data.type === \"group\") && !data.emailAddress) {\n return errorResponse(`Email address is required when sharing with type \"${data.type}\"`);\n }\n\n // Validate domain required for domain type\n if (data.type === \"domain\" && !data.domain) {\n return errorResponse('Domain is required when sharing with type \"domain\"');\n }\n\n // Get file name for response\n const file = await drive.files.get({\n fileId: data.fileId,\n fields: \"name\",\n supportsAllDrives: true,\n });\n\n const permissionBody: {\n role: string;\n type: string;\n emailAddress?: string;\n domain?: string;\n } = {\n role: data.role,\n type: data.type,\n };\n\n if (data.emailAddress) {\n permissionBody.emailAddress = data.emailAddress;\n }\n if (data.domain) {\n permissionBody.domain = data.domain;\n }\n\n const createParams: drive_v3.Params$Resource$Permissions$Create = {\n fileId: data.fileId,\n requestBody: permissionBody,\n supportsAllDrives: true,\n };\n\n // Only include notification params for user/group types (Google rejects for anyone/domain)\n if (data.type === \"user\" || data.type === \"group\") {\n createParams.sendNotificationEmail = data.sendNotificationEmail;\n if (data.emailMessage) {\n createParams.emailMessage = data.emailMessage;\n }\n }\n\n const permission = await drive.permissions.create(createParams);\n\n log(\"File shared successfully\", {\n fileId: data.fileId,\n permissionId: permission.data.id,\n });\n\n let targetDesc = \"\";\n if (data.type === \"anyone\") {\n targetDesc = \"anyone with the link\";\n } else if (data.type === \"domain\") {\n targetDesc = `anyone in ${data.domain}`;\n } else {\n targetDesc = data.emailAddress || \"\";\n }\n\n return successResponse(\n `Shared \"${file.data.name}\" with ${targetDesc} as ${data.role}\\n` +\n `Permission ID: ${permission.data.id}`,\n );\n}\n\nexport async function handleGetSharing(\n drive: drive_v3.Drive,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(GetSharingSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Get file name\n const file = await withTimeout(\n drive.files.get({\n fileId: data.fileId,\n fields: \"name, webViewLink\",\n supportsAllDrives: true,\n }),\n 30000,\n \"Get file info\",\n );\n\n // Get permissions\n const permissions = await withTimeout(\n drive.permissions.list({\n fileId: data.fileId,\n fields: \"permissions(id, role, type, emailAddress, domain, displayName)\",\n supportsAllDrives: true,\n }),\n 30000,\n \"List permissions\",\n );\n\n const permissionList = permissions.data.permissions || [];\n\n const formattedPermissions = permissionList\n .map((p) => {\n let target = \"\";\n if (p.type === \"anyone\") {\n target = \"Anyone with the link\";\n } else if (p.type === \"domain\") {\n target = `Anyone in ${p.domain}`;\n } else {\n target = p.emailAddress || p.displayName || \"Unknown\";\n }\n return `\u2022 ${target}: ${p.role} (ID: ${p.id})`;\n })\n .join(\"\\n\");\n\n const textResponse = `Sharing settings for \"${file.data.name}\":\\n\\n${formattedPermissions}\\n\\nLink: ${file.data.webViewLink}`;\n\n return structuredResponse(textResponse, {\n fileName: file.data.name,\n webViewLink: file.data.webViewLink,\n permissions: permissionList.map((p) => ({\n id: p.id,\n role: p.role,\n type: p.type,\n emailAddress: p.emailAddress,\n domain: p.domain,\n displayName: p.displayName,\n })),\n });\n}\n\n// -----------------------------------------------------------------------------\n// REVISION HANDLERS\n// -----------------------------------------------------------------------------\n\nexport async function handleListRevisions(\n drive: drive_v3.Drive,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(ListRevisionsSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Get file name\n const file = await withTimeout(\n drive.files.get({\n fileId: data.fileId,\n fields: \"name, mimeType\",\n supportsAllDrives: true,\n }),\n 30000,\n \"Get file info\",\n );\n\n // Check if file supports revisions (Google Workspace files use different versioning)\n if (file.data.mimeType?.startsWith(\"application/vnd.google-apps\")) {\n return errorResponse(\n `Google Workspace files (${file.data.mimeType}) do not support revision history through this API. ` +\n `Use the Google Docs/Sheets/Slides UI to view version history.`,\n );\n }\n\n const revisions = await withTimeout(\n drive.revisions.list({\n fileId: data.fileId,\n pageSize: data.pageSize || 100,\n fields: \"revisions(id, modifiedTime, lastModifyingUser, size, keepForever)\",\n }),\n 30000,\n \"List revisions\",\n );\n\n const revisionList = revisions.data.revisions || [];\n\n if (revisionList.length === 0) {\n return successResponse(`No revisions found for \"${file.data.name}\".`);\n }\n\n const formattedRevisions = revisionList\n .map((r, idx) => {\n const author =\n r.lastModifyingUser?.displayName || r.lastModifyingUser?.emailAddress || \"Unknown\";\n const sizeStr = formatBytes(r.size);\n const keepForever = r.keepForever ? \" (pinned)\" : \"\";\n return `${idx + 1}. ID: ${r.id} | ${r.modifiedTime} | ${author} | ${sizeStr}${keepForever}`;\n })\n .join(\"\\n\");\n\n const textResponse = `Revisions for \"${file.data.name}\" (${revisionList.length} found):\\n\\n${formattedRevisions}`;\n\n return structuredResponse(textResponse, {\n fileName: file.data.name,\n revisions: revisionList.map((r) => ({\n id: r.id,\n modifiedTime: r.modifiedTime,\n size: r.size,\n keepForever: r.keepForever,\n lastModifyingUser: r.lastModifyingUser\n ? {\n displayName: r.lastModifyingUser.displayName,\n emailAddress: r.lastModifyingUser.emailAddress,\n }\n : undefined,\n })),\n });\n}\n\nexport async function handleRestoreRevision(\n drive: drive_v3.Drive,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(RestoreRevisionSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Get file metadata\n const file = await drive.files.get({\n fileId: data.fileId,\n fields: \"name, mimeType\",\n supportsAllDrives: true,\n });\n\n // Check if file supports revisions\n if (file.data.mimeType?.startsWith(\"application/vnd.google-apps\")) {\n return errorResponse(\n `Google Workspace files cannot be restored through this API. ` +\n `Use the Google Docs/Sheets/Slides UI to restore previous versions.`,\n );\n }\n\n // Get revision content\n const revisionContent = await drive.revisions.get(\n { fileId: data.fileId, revisionId: data.revisionId, alt: \"media\" },\n { responseType: \"arraybuffer\" },\n );\n\n // Update file with revision content\n const { Readable } = await import(\"stream\");\n const stream = Readable.from(Buffer.from(revisionContent.data as ArrayBuffer));\n\n await drive.files.update({\n fileId: data.fileId,\n media: {\n mimeType: file.data.mimeType || \"application/octet-stream\",\n body: stream,\n },\n supportsAllDrives: true,\n });\n\n log(\"Revision restored successfully\", {\n fileId: data.fileId,\n revisionId: data.revisionId,\n });\n return successResponse(`Restored \"${file.data.name}\" to revision ${data.revisionId}`);\n}\n\n// -----------------------------------------------------------------------------\n// BINARY FILE HANDLERS\n// -----------------------------------------------------------------------------\n\nconst COMMON_MIME_TYPES: Record<string, string> = {\n pdf: \"application/pdf\",\n png: \"image/png\",\n jpg: \"image/jpeg\",\n jpeg: \"image/jpeg\",\n gif: \"image/gif\",\n webp: \"image/webp\",\n svg: \"image/svg+xml\",\n mp4: \"video/mp4\",\n mp3: \"audio/mpeg\",\n zip: \"application/zip\",\n json: \"application/json\",\n xml: \"application/xml\",\n html: \"text/html\",\n css: \"text/css\",\n js: \"application/javascript\",\n};\n\nexport async function handleDownloadFile(\n drive: drive_v3.Drive,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(DownloadFileSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Get file metadata\n const file = await drive.files.get({\n fileId: data.fileId,\n fields: \"name, mimeType, size\",\n supportsAllDrives: true,\n });\n\n const mimeType = file.data.mimeType || \"\";\n const fileName = file.data.name || \"download\";\n\n // Reject Google Workspace files\n if (mimeType.startsWith(\"application/vnd.google-apps\")) {\n return errorResponse(\n `\"${fileName}\" is a Google Workspace file (${mimeType}). ` +\n `Use exportFile instead to convert it to a downloadable format.`,\n );\n }\n\n // Download file content\n const response = await drive.files.get(\n { fileId: data.fileId, alt: \"media\", supportsAllDrives: true },\n { responseType: \"arraybuffer\" },\n );\n\n const buffer = Buffer.from(response.data as ArrayBuffer);\n\n // If outputPath provided, save to file\n if (data.outputPath) {\n const fs = await import(\"fs/promises\");\n const path = await import(\"path\");\n\n const fullPath = path.join(data.outputPath, fileName);\n await fs.writeFile(fullPath, buffer);\n\n log(\"File downloaded successfully\", {\n fileId: data.fileId,\n outputPath: fullPath,\n });\n return successResponse(\n `Downloaded \"${fileName}\" to: ${fullPath}\\n` +\n `Size: ${buffer.length} bytes\\n` +\n `Type: ${mimeType}`,\n );\n }\n\n // Otherwise return base64\n const base64Content = buffer.toString(\"base64\");\n\n log(\"File downloaded successfully\", {\n fileId: data.fileId,\n size: buffer.length,\n });\n return successResponse(\n `Downloaded \"${fileName}\"\\n` +\n `Size: ${buffer.length} bytes\\n` +\n `Type: ${mimeType}\\n\\n` +\n `Base64 content:\\n${base64Content}`,\n );\n}\n\nexport async function handleUploadFile(\n drive: drive_v3.Drive,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(UploadFileSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Require either sourcePath or base64Content\n if (!data.sourcePath && !data.base64Content) {\n return errorResponse(\"Either sourcePath or base64Content is required\");\n }\n\n // Auto-detect mimeType from extension if not provided\n let mimeType = data.mimeType;\n if (!mimeType) {\n const ext = data.name.split(\".\").pop()?.toLowerCase() || \"\";\n mimeType = COMMON_MIME_TYPES[ext] || \"application/octet-stream\";\n }\n\n // Resolve folder ID (supports both folderId and folderPath)\n const folderId = await resolveOptionalFolderPath(drive, data.folderId, data.folderPath);\n\n // Check if file already exists\n const existingFileId = await checkFileExists(drive, data.name, folderId);\n if (existingFileId) {\n return errorResponse(\n `A file named \"${data.name}\" already exists in this location. ` +\n `Existing file ID: ${existingFileId}`,\n );\n }\n\n // Prepare content stream\n let mediaBody: NodeJS.ReadableStream;\n if (data.sourcePath) {\n const fs = await import(\"fs\");\n mediaBody = fs.createReadStream(data.sourcePath);\n } else {\n const { Readable } = await import(\"stream\");\n const buffer = Buffer.from(data.base64Content!, \"base64\");\n mediaBody = Readable.from(buffer);\n }\n\n // Upload file\n const file = await drive.files.create({\n requestBody: {\n name: data.name,\n parents: [folderId],\n },\n media: {\n mimeType,\n body: mediaBody,\n },\n fields: \"id, name, webViewLink\",\n supportsAllDrives: true,\n });\n\n log(\"File uploaded successfully\", {\n fileId: file.data.id,\n name: file.data.name,\n });\n return successResponse(\n `Uploaded file: ${file.data.name}\\n` +\n `ID: ${file.data.id}\\n` +\n `Link: ${file.data.webViewLink}`,\n );\n}\n\n// -----------------------------------------------------------------------------\n// METADATA HANDLERS\n// -----------------------------------------------------------------------------\n\nexport async function handleGetStorageQuota(\n drive: drive_v3.Drive,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(GetStorageQuotaSchema, args);\n if (!validation.success) return validation.response;\n\n const about = await withTimeout(\n drive.about.get({\n fields: \"storageQuota, user\",\n }),\n 30000,\n \"Get storage quota\",\n );\n\n const quota = about.data.storageQuota;\n const user = about.data.user;\n\n if (!quota) {\n return errorResponse(\"Unable to retrieve storage quota information\");\n }\n\n const limit = quota.limit ? formatBytes(quota.limit) : \"Unlimited\";\n const usage = formatBytes(quota.usage);\n const usageInDrive = formatBytes(quota.usageInDrive);\n const usageInTrash = formatBytes(quota.usageInDriveTrash);\n\n let available = \"Unlimited\";\n if (quota.limit && quota.usage) {\n const availableBytes = parseInt(quota.limit) - parseInt(quota.usage);\n available = formatBytes(String(availableBytes));\n }\n\n const textResponse =\n `Google Drive Storage Quota\\n` +\n `User: ${user?.emailAddress || \"Unknown\"}\\n\\n` +\n `Total limit: ${limit}\\n` +\n `Total usage: ${usage}\\n` +\n `Usage in Drive: ${usageInDrive}\\n` +\n `Usage in Trash: ${usageInTrash}\\n` +\n `Available: ${available}`;\n\n return structuredResponse(textResponse, {\n user: user\n ? {\n displayName: user.displayName,\n emailAddress: user.emailAddress,\n }\n : undefined,\n storageQuota: {\n limit: quota.limit,\n usage: quota.usage,\n usageInDrive: quota.usageInDrive,\n usageInDriveTrash: quota.usageInDriveTrash,\n },\n });\n}\n\nexport async function handleStarFile(drive: drive_v3.Drive, args: unknown): Promise<ToolResponse> {\n const validation = validateArgs(StarFileSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Get file name\n const file = await drive.files.get({\n fileId: data.fileId,\n fields: \"name\",\n supportsAllDrives: true,\n });\n\n // Update starred status\n await drive.files.update({\n fileId: data.fileId,\n requestBody: { starred: data.starred },\n supportsAllDrives: true,\n });\n\n const action = data.starred ? \"starred\" : \"unstarred\";\n log(`File ${action} successfully`, { fileId: data.fileId });\n return successResponse(`Successfully ${action} \"${file.data.name}\"`);\n}\n\n// -----------------------------------------------------------------------------\n// FILE PATH RESOLUTION - HELPERS\n// -----------------------------------------------------------------------------\n\ninterface PathSegmentQuery {\n folderId: string;\n segmentName: string;\n isLastSegment: boolean;\n targetType?: \"file\" | \"folder\" | \"any\";\n}\n\nfunction buildPathSegmentQuery(params: PathSegmentQuery): string {\n const { folderId, segmentName, isLastSegment, targetType } = params;\n const escapedName = escapeQueryString(segmentName);\n\n let query = combineQueries(\n `'${folderId}' in parents`,\n `name = '${escapedName}'`,\n \"trashed = false\",\n );\n\n if (isLastSegment && targetType !== \"any\") {\n if (targetType === \"folder\") {\n query += ` and mimeType = '${FOLDER_MIME_TYPE}'`;\n } else if (targetType === \"file\") {\n query += ` and mimeType != '${FOLDER_MIME_TYPE}'`;\n }\n } else if (!isLastSegment) {\n query += ` and mimeType = '${FOLDER_MIME_TYPE}'`;\n }\n\n return query;\n}\n\nasync function buildNotFoundError(\n drive: drive_v3.Drive,\n segment: string,\n folderId: string,\n resolvedPath: string[],\n): Promise<string> {\n const pathSoFar = \"/\" + resolvedPath.join(\"/\");\n const searchedIn =\n resolvedPath.length > 0 ? `\"${resolvedPath[resolvedPath.length - 1]}\"` : \"root\";\n\n const contentsResponse = await drive.files.list({\n q: `'${folderId}' in parents and trashed = false`,\n fields: \"files(name, mimeType)\",\n pageSize: 20,\n includeItemsFromAllDrives: true,\n supportsAllDrives: true,\n });\n\n const contents = (contentsResponse.data.files || [])\n .map((f) => (f.mimeType === FOLDER_MIME_TYPE ? `\uD83D\uDCC1 ${f.name}` : `\uD83D\uDCC4 ${f.name}`))\n .slice(0, 10);\n\n const contentsStr =\n contents.length > 0\n ? `\\nContents of ${searchedIn}: ${contents.join(\", \")}${contents.length >= 10 ? \"...\" : \"\"}`\n : `\\n${searchedIn} appears to be empty.`;\n\n return `Path segment \"${segment}\" not found at \"${pathSoFar || \"/\"}\".${contentsStr}`;\n}\n\ninterface ResolvedFileInfo {\n id: string;\n name: string;\n mimeType: string | null | undefined;\n modifiedTime: string | null | undefined;\n}\n\nfunction buildResolvedResponse(\n file: ResolvedFileInfo,\n originalPath: string,\n resolvedPath: string[],\n): ToolResponse {\n const typeLabel = file.mimeType === FOLDER_MIME_TYPE ? \"folder\" : \"file\";\n return structuredResponse(`Resolved \"${originalPath}\" to ${typeLabel} \"${file.name}\"`, {\n id: file.id,\n name: file.name,\n path: \"/\" + resolvedPath.join(\"/\"),\n mimeType: file.mimeType,\n modifiedTime: file.modifiedTime,\n });\n}\n\nasync function handleMultipleMatches(\n files: drive_v3.Schema$File[],\n segment: string,\n resolvedPath: string[],\n context: HandlerContext | undefined,\n): Promise<{ selectedFile?: drive_v3.Schema$File; error?: string }> {\n if (!context?.server) {\n const message = formatDisambiguationOptions(\n files.map((f) => ({\n id: f.id!,\n name: f.name!,\n mimeType: f.mimeType || undefined,\n modifiedTime: f.modifiedTime,\n })),\n `Multiple items named \"${segment}\" found at \"/${resolvedPath.join(\"/\")}\".`,\n );\n return { error: message };\n }\n\n const fileOptions = files.map((f) => ({\n id: f.id!,\n name: f.name!,\n mimeType: f.mimeType || undefined,\n modifiedTime: f.modifiedTime || undefined,\n path: \"/\" + [...resolvedPath, f.name!].join(\"/\"),\n }));\n\n const result = await elicitFileSelection(\n context.server,\n fileOptions,\n `Multiple items named \"${segment}\" found at \"/${resolvedPath.join(\"/\")}\". Please select one:`,\n );\n\n if (result.cancelled) return { error: \"File selection cancelled\" };\n if (result.error) return { error: result.error };\n if (result.selectedFileId) {\n const selected = files.find((f) => f.id === result.selectedFileId);\n return { selectedFile: selected };\n }\n return { error: \"No file selected\" };\n}\n\n// -----------------------------------------------------------------------------\n// FILE PATH RESOLUTION\n// -----------------------------------------------------------------------------\n\nexport async function handleResolveFilePath(\n drive: drive_v3.Drive,\n args: unknown,\n context?: HandlerContext,\n): Promise<ToolResponse> {\n const validation = validateArgs(ResolveFilePathSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n if (!data.path || data.path === \"/\") {\n return structuredResponse(\"Resolved to root folder\", {\n id: \"root\",\n name: \"My Drive\",\n path: \"/\",\n mimeType: FOLDER_MIME_TYPE,\n modifiedTime: null,\n });\n }\n\n const parts = data.path.replace(/^\\/+|\\/+$/g, \"\").split(\"/\");\n let currentFolderId = \"root\";\n const resolvedPath: string[] = [];\n\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i];\n if (!part) continue;\n\n const isLastPart = i === parts.length - 1;\n const query = buildPathSegmentQuery({\n folderId: currentFolderId,\n segmentName: part,\n isLastSegment: isLastPart,\n targetType: data.type,\n });\n\n const response = await drive.files.list({\n q: query,\n fields: \"files(id, name, mimeType, modifiedTime)\",\n pageSize: 10,\n includeItemsFromAllDrives: true,\n supportsAllDrives: true,\n });\n\n const files = response.data.files || [];\n\n if (files.length === 0) {\n const errorMsg = await buildNotFoundError(drive, part, currentFolderId, resolvedPath);\n return errorResponse(errorMsg);\n }\n\n if (files.length > 1) {\n const result = await handleMultipleMatches(files, part, resolvedPath, context);\n if (result.error) return errorResponse(result.error);\n if (result.selectedFile) {\n resolvedPath.push(result.selectedFile.name!);\n if (isLastPart) {\n log(\"Path resolved via elicitation\", { path: data.path, fileId: result.selectedFile.id });\n return buildResolvedResponse(\n {\n id: result.selectedFile.id!,\n name: result.selectedFile.name!,\n mimeType: result.selectedFile.mimeType,\n modifiedTime: result.selectedFile.modifiedTime,\n },\n data.path,\n resolvedPath,\n );\n }\n currentFolderId = result.selectedFile.id!;\n continue;\n }\n }\n\n const file = files[0];\n resolvedPath.push(file.name!);\n\n if (isLastPart) {\n log(\"Path resolved successfully\", { path: data.path, fileId: file.id });\n return buildResolvedResponse(\n {\n id: file.id!,\n name: file.name!,\n mimeType: file.mimeType,\n modifiedTime: file.modifiedTime,\n },\n data.path,\n resolvedPath,\n );\n }\n\n currentFolderId = file.id!;\n }\n\n return errorResponse(\"Unable to resolve path\");\n}\n\n// -----------------------------------------------------------------------------\n// BATCH OPERATIONS\n// -----------------------------------------------------------------------------\n\nexport async function handleBatchDelete(\n drive: drive_v3.Drive,\n args: unknown,\n context?: HandlerContext,\n): Promise<ToolResponse> {\n const validation = validateArgs(BatchDeleteSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n const { success: deleted, failed } = await processBatchOperation(\n data.fileIds,\n async (fileId) => {\n const file = await drive.files.get({\n fileId,\n fields: \"name\",\n supportsAllDrives: true,\n });\n\n await drive.files.update({\n fileId,\n requestBody: { trashed: true },\n supportsAllDrives: true,\n });\n\n return { fileId, name: file.data.name };\n },\n context,\n { operationName: \"Deleting files\" },\n );\n\n const summary = `Batch delete: ${deleted.length} succeeded, ${failed.length} failed`;\n log(summary, { deleted: deleted.length, failed: failed.length });\n\n return structuredResponse(\n summary +\n (deleted.length > 0\n ? `\\n\\nDeleted: ${deleted.map((d) => d.name || d.fileId).join(\", \")}`\n : \"\") +\n (failed.length > 0\n ? `\\n\\nFailed: ${failed.map((f) => `${f.id}: ${f.error}`).join(\", \")}`\n : \"\"),\n { deleted, failed },\n );\n}\n\nexport async function handleBatchMove(\n drive: drive_v3.Drive,\n args: unknown,\n context?: HandlerContext,\n): Promise<ToolResponse> {\n const validation = validateArgs(BatchMoveSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Resolve destination folder (supports both ID and path)\n const destinationFolderId = await resolveOptionalFolderPath(\n drive,\n data.destinationFolderId,\n data.destinationPath,\n );\n\n // Get destination folder name for better reporting\n let destName = \"root\";\n if (destinationFolderId !== \"root\") {\n try {\n const destFolder = await withRetry(\n () =>\n drive.files.get({\n fileId: destinationFolderId,\n fields: \"name\",\n supportsAllDrives: true,\n }),\n { operationName: \"getDestinationFolder\" },\n );\n destName = destFolder.data.name || destinationFolderId;\n } catch {\n return errorResponse(`Destination folder not found: ${destinationFolderId}`);\n }\n }\n\n const { success: moved, failed } = await processBatchOperation(\n data.fileIds,\n async (fileId) => {\n const file = await drive.files.get({\n fileId,\n fields: \"name, parents\",\n supportsAllDrives: true,\n });\n\n const previousParents = (file.data.parents || []).join(\",\");\n\n await drive.files.update({\n fileId,\n addParents: destinationFolderId,\n removeParents: previousParents,\n supportsAllDrives: true,\n });\n\n return { fileId, name: file.data.name };\n },\n context,\n { operationName: `Moving files to \"${destName}\"` },\n );\n\n const summary = `Batch move to \"${destName}\": ${moved.length} succeeded, ${failed.length} failed`;\n log(summary, { moved: moved.length, failed: failed.length });\n\n return structuredResponse(\n summary +\n (moved.length > 0 ? `\\n\\nMoved: ${moved.map((m) => m.name || m.fileId).join(\", \")}` : \"\") +\n (failed.length > 0\n ? `\\n\\nFailed: ${failed.map((f) => `${f.id}: ${f.error}`).join(\", \")}`\n : \"\"),\n {\n moved,\n failed,\n destinationFolder: { id: destinationFolderId, name: destName },\n },\n );\n}\n\nexport async function handleBatchShare(\n drive: drive_v3.Drive,\n args: unknown,\n context?: HandlerContext,\n): Promise<ToolResponse> {\n const validation = validateArgs(BatchShareSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n const { success: shared, failed } = await processBatchOperation(\n data.fileIds,\n async (fileId) => {\n const file = await drive.files.get({\n fileId,\n fields: \"name\",\n supportsAllDrives: true,\n });\n\n await drive.permissions.create({\n fileId,\n requestBody: {\n role: data.role,\n type: \"user\",\n emailAddress: data.email,\n },\n sendNotificationEmail: data.sendNotification,\n supportsAllDrives: true,\n });\n\n return { fileId, name: file.data.name };\n },\n context,\n { operationName: `Sharing files with ${data.email}` },\n );\n\n const summary = `Batch share with ${data.email} (${data.role}): ${shared.length} succeeded, ${failed.length} failed`;\n log(summary, { shared: shared.length, failed: failed.length });\n\n return structuredResponse(\n summary +\n (shared.length > 0 ? `\\n\\nShared: ${shared.map((s) => s.name || s.fileId).join(\", \")}` : \"\") +\n (failed.length > 0\n ? `\\n\\nFailed: ${failed.map((f) => `${f.id}: ${f.error}`).join(\", \")}`\n : \"\"),\n { shared, failed, shareDetails: { email: data.email, role: data.role } },\n );\n}\n\nexport async function handleBatchRestore(\n drive: drive_v3.Drive,\n args: unknown,\n context?: HandlerContext,\n): Promise<ToolResponse> {\n const validation = validateArgs(BatchRestoreSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n const { success: restored, failed } = await processBatchOperation(\n data.fileIds,\n async (fileId) => {\n const file = await drive.files.get({\n fileId,\n fields: \"name, trashed\",\n supportsAllDrives: true,\n });\n\n if (!file.data.trashed) {\n throw new Error(`File \"${file.data.name}\" is not in trash`);\n }\n\n await drive.files.update({\n fileId,\n requestBody: { trashed: false },\n supportsAllDrives: true,\n });\n\n return { fileId, name: file.data.name };\n },\n context,\n { operationName: \"Restoring files from trash\" },\n );\n\n const summary = `Batch restore: ${restored.length} succeeded, ${failed.length} failed`;\n log(summary, { restored: restored.length, failed: failed.length });\n\n return structuredResponse(\n summary +\n (restored.length > 0\n ? `\\n\\nRestored: ${restored.map((r) => r.name || r.fileId).join(\", \")}`\n : \"\") +\n (failed.length > 0\n ? `\\n\\nFailed: ${failed.map((f) => `${f.id}: ${f.error}`).join(\", \")}`\n : \"\"),\n { restored, failed },\n );\n}\n\n// -----------------------------------------------------------------------------\n// PERMISSION MANAGEMENT\n// -----------------------------------------------------------------------------\n\nexport async function handleRemovePermission(\n drive: drive_v3.Drive,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(RemovePermissionSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Get file name for reporting\n const file = await drive.files.get({\n fileId: data.fileId,\n fields: \"name\",\n supportsAllDrives: true,\n });\n\n let permissionIdToRemove = data.permissionId;\n\n // If email provided, look up the permission ID\n if (data.email && !permissionIdToRemove) {\n const permissions = await drive.permissions.list({\n fileId: data.fileId,\n fields: \"permissions(id, emailAddress, role)\",\n supportsAllDrives: true,\n });\n\n const permission = (permissions.data.permissions || []).find(\n (p) => p.emailAddress?.toLowerCase() === data.email!.toLowerCase(),\n );\n\n if (!permission) {\n // List current permissions for context\n const currentPerms = (permissions.data.permissions || [])\n .map((p) => `${p.emailAddress || \"anonymous\"} (${p.role})`)\n .join(\", \");\n\n return errorResponse(\n `No permission found for email \"${data.email}\" on file \"${file.data.name}\". ` +\n `Current permissions: ${currentPerms || \"none\"}`,\n );\n }\n\n // Check if this is the owner\n if (permission.role === \"owner\") {\n return errorResponse(\n `Cannot remove owner permission for \"${data.email}\". ` +\n `Transfer ownership first if you want to remove this user's access.`,\n );\n }\n\n permissionIdToRemove = permission.id!;\n }\n\n // Check if trying to remove owner by permissionId\n if (permissionIdToRemove) {\n const permDetails = await drive.permissions.get({\n fileId: data.fileId,\n permissionId: permissionIdToRemove,\n fields: \"role, emailAddress\",\n supportsAllDrives: true,\n });\n\n if (permDetails.data.role === \"owner\") {\n return errorResponse(\n `Cannot remove owner permission (${permDetails.data.emailAddress}). ` +\n `Transfer ownership first if you want to remove this user's access.`,\n );\n }\n }\n\n await drive.permissions.delete({\n fileId: data.fileId,\n permissionId: permissionIdToRemove!,\n supportsAllDrives: true,\n });\n\n log(\"Permission removed successfully\", {\n fileId: data.fileId,\n permissionId: permissionIdToRemove,\n });\n return successResponse(\n `Removed permission from \"${file.data.name}\"` +\n (data.email ? ` for ${data.email}` : ` (permission ID: ${permissionIdToRemove})`),\n );\n}\n\n// -----------------------------------------------------------------------------\n// TRASH MANAGEMENT\n// -----------------------------------------------------------------------------\n\nexport async function handleListTrash(drive: drive_v3.Drive, args: unknown): Promise<ToolResponse> {\n const validation = validateArgs(ListTrashSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n const response = await withTimeout(\n drive.files.list({\n q: \"trashed = true\",\n pageSize: data.pageSize,\n pageToken: data.pageToken,\n fields: \"nextPageToken, files(id, name, mimeType, modifiedTime, size, trashedTime)\",\n includeItemsFromAllDrives: true,\n supportsAllDrives: true,\n }),\n 30000,\n \"List trash\",\n );\n\n const files = response.data.files || [];\n\n if (files.length === 0) {\n return structuredResponse(\"Trash is empty\", {\n files: [],\n nextPageToken: null,\n });\n }\n\n const fileList = files\n .map((f) => {\n const icon = f.mimeType === FOLDER_MIME_TYPE ? \"\uD83D\uDCC1\" : \"\uD83D\uDCC4\";\n const size = f.mimeType === FOLDER_MIME_TYPE ? \"\" : ` (${formatBytesCompact(f.size)})`;\n return `${icon} ${f.name}${size} - ID: ${f.id}`;\n })\n .join(\"\\n\");\n\n const textResponse =\n `Trash contents (${files.length} items):\\n\\n${fileList}` +\n (response.data.nextPageToken\n ? \"\\n\\n(More items available - use nextPageToken to continue)\"\n : \"\");\n\n return structuredResponse(textResponse, {\n files: files.map((f) => ({\n id: f.id,\n name: f.name,\n mimeType: f.mimeType,\n size: f.size,\n trashedTime: f.trashedTime,\n })),\n nextPageToken: response.data.nextPageToken || null,\n });\n}\n\nexport async function handleRestoreFromTrash(\n drive: drive_v3.Drive,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(RestoreFromTrashSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Get file info\n const file = await drive.files.get({\n fileId: data.fileId,\n fields: \"name, trashed, parents\",\n supportsAllDrives: true,\n });\n\n if (!file.data.trashed) {\n return errorResponse(`File \"${file.data.name}\" is not in trash`, {\n code: \"INVALID_INPUT\",\n context: { fileId: data.fileId },\n });\n }\n\n // First, restore from trash\n await drive.files.update({\n fileId: data.fileId,\n requestBody: { trashed: false },\n supportsAllDrives: true,\n });\n\n // If destination is specified, move to that folder\n let destinationInfo: { id: string; name: string } | undefined;\n if (data.destinationFolderId || data.destinationPath) {\n const destinationFolderId = await resolveOptionalFolderPath(\n drive,\n data.destinationFolderId,\n data.destinationPath,\n );\n\n // Get destination folder name\n let destName = \"root\";\n if (destinationFolderId !== \"root\") {\n const destFolder = await drive.files.get({\n fileId: destinationFolderId,\n fields: \"name\",\n supportsAllDrives: true,\n });\n destName = destFolder.data.name || destinationFolderId;\n }\n\n // Move to destination\n const currentParents = file.data.parents?.join(\",\") || \"\";\n await drive.files.update({\n fileId: data.fileId,\n addParents: destinationFolderId,\n removeParents: currentParents,\n supportsAllDrives: true,\n });\n\n destinationInfo = { id: destinationFolderId, name: destName };\n log(\"File restored from trash and moved\", {\n fileId: data.fileId,\n destinationFolderId,\n });\n return structuredResponse(\n `Restored \"${file.data.name}\" from trash and moved to \"${destName}\"`,\n {\n fileName: file.data.name,\n restored: true,\n destinationFolder: destinationInfo,\n },\n );\n }\n\n log(\"File restored from trash\", { fileId: data.fileId });\n return structuredResponse(`Restored \"${file.data.name}\" from trash`, {\n fileName: file.data.name,\n restored: true,\n });\n}\n\nexport async function handleEmptyTrash(\n drive: drive_v3.Drive,\n args: unknown,\n context?: HandlerContext,\n): Promise<ToolResponse> {\n const validation = validateArgs(EmptyTrashSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Count items in trash first\n const listParams: {\n q: string;\n fields: string;\n pageSize: number;\n driveId?: string;\n corpora?: string;\n } = {\n q: \"trashed = true\",\n fields: \"files(id, name)\",\n pageSize: 1000,\n };\n\n // If driveId is specified, query that shared drive's trash\n if (data.driveId) {\n listParams.driveId = data.driveId;\n listParams.corpora = \"drive\";\n }\n\n const trashContents = await drive.files.list(listParams);\n\n const itemCount = trashContents.data.files?.length || 0;\n\n if (itemCount === 0) {\n return successResponse(\n data.driveId ? \"Shared drive trash is already empty\" : \"Trash is already empty\",\n );\n }\n\n // Use elicitation for confirmation if context available\n if (context?.server) {\n const sampleFiles = (trashContents.data.files || [])\n .slice(0, 5)\n .map((f) => f.name)\n .join(\", \");\n const moreText = itemCount > 5 ? ` and ${itemCount - 5} more` : \"\";\n\n const confirmResult = await elicitConfirmation(\n context.server,\n `Permanently delete ${itemCount} item(s) from ${data.driveId ? \"shared drive \" : \"\"}trash?`,\n `This action cannot be undone. Files: ${sampleFiles}${moreText}`,\n );\n\n if (confirmResult.cancelled) {\n return errorResponse(\"Empty trash operation cancelled\");\n }\n\n if (!confirmResult.confirmed) {\n return errorResponse(\n `Empty trash requires confirmation. ${itemCount} item(s) will be permanently deleted. ` +\n `Files include: ${sampleFiles}${moreText}`,\n );\n }\n }\n\n // Empty trash - pass driveId if specified for shared drives\n await drive.files.emptyTrash(data.driveId ? { driveId: data.driveId } : {});\n\n log(\"Trash emptied\", { itemCount, driveId: data.driveId });\n return successResponse(\n data.driveId\n ? `Permanently deleted ${itemCount} item(s) from shared drive trash`\n : `Permanently deleted ${itemCount} item(s) from trash`,\n );\n}\n\n// -----------------------------------------------------------------------------\n// FOLDER TREE DISCOVERY\n// -----------------------------------------------------------------------------\n\ninterface FolderTreeNode {\n id: string;\n name: string;\n type: \"folder\" | \"file\";\n mimeType?: string;\n children?: FolderTreeNode[];\n truncated?: boolean;\n}\n\nasync function buildFolderTree(\n drive: drive_v3.Drive,\n folderId: string,\n folderName: string,\n currentDepth: number,\n maxDepth: number,\n): Promise<FolderTreeNode> {\n const node: FolderTreeNode = {\n id: folderId,\n name: folderName,\n type: \"folder\",\n };\n\n if (currentDepth >= maxDepth) {\n return node;\n }\n\n // List contents of this folder\n const response = await drive.files.list({\n q: `'${folderId}' in parents and trashed = false`,\n fields: \"files(id, name, mimeType)\",\n pageSize: 100,\n orderBy: \"folder,name\",\n includeItemsFromAllDrives: true,\n supportsAllDrives: true,\n });\n\n const files = response.data.files || [];\n const children: FolderTreeNode[] = [];\n\n // Check if results were truncated (100 is pageSize limit)\n const truncated = files.length >= 100;\n\n for (const file of files) {\n if (file.mimeType === FOLDER_MIME_TYPE) {\n // Recursively build tree for subfolders\n const childNode = await buildFolderTree(\n drive,\n file.id!,\n file.name!,\n currentDepth + 1,\n maxDepth,\n );\n children.push(childNode);\n } else {\n // Add file node\n children.push({\n id: file.id!,\n name: file.name!,\n type: \"file\",\n mimeType: file.mimeType || undefined,\n });\n }\n }\n\n if (children.length > 0) {\n node.children = children;\n }\n\n if (truncated) {\n node.truncated = true;\n }\n\n return node;\n}\n\nfunction formatTreeAsText(\n node: FolderTreeNode,\n indent: string = \"\",\n isLast: boolean = true,\n): string {\n const prefix = indent + (isLast ? \"\u2514\u2500\u2500 \" : \"\u251C\u2500\u2500 \");\n const icon = node.type === \"folder\" ? \"\uD83D\uDCC1\" : \"\uD83D\uDCC4\";\n const truncatedIndicator = node.truncated ? \" (100+ items, truncated)\" : \"\";\n let result = prefix + icon + \" \" + node.name + truncatedIndicator + \"\\n\";\n\n if (node.children) {\n const childIndent = indent + (isLast ? \" \" : \"\u2502 \");\n node.children.forEach((child, index) => {\n const isLastChild = index === node.children!.length - 1;\n result += formatTreeAsText(child, childIndent, isLastChild);\n });\n }\n\n return result;\n}\n\nexport async function handleGetFolderTree(\n drive: drive_v3.Drive,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(GetFolderTreeSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Resolve folder ID\n const folderId = await resolveOptionalFolderPath(drive, data.folderId, data.folderPath);\n\n // Get folder name\n let folderName = \"My Drive\";\n let folderPath = \"/\";\n\n if (folderId !== \"root\") {\n const folder = await drive.files.get({\n fileId: folderId,\n fields: \"name\",\n supportsAllDrives: true,\n });\n folderName = folder.data.name || folderId;\n folderPath = data.folderPath || `/${folderName}`;\n }\n\n // Build tree structure\n const tree = await buildFolderTree(drive, folderId, folderName, 0, data.depth || 2);\n\n // Format as text\n const truncatedIndicator = tree.truncated ? \" (100+ items, truncated)\" : \"\";\n const treeText =\n \"\uD83D\uDCC1 \" +\n folderName +\n truncatedIndicator +\n \"\\n\" +\n (tree.children\n ? tree.children\n .map((child, index) => formatTreeAsText(child, \"\", index === tree.children!.length - 1))\n .join(\"\")\n : \"(empty)\");\n\n return structuredResponse(treeText, {\n id: folderId,\n name: folderName,\n path: folderPath,\n children: tree.children || [],\n truncated: tree.truncated,\n });\n}\n", "/**\n * Google Drive query building utilities.\n *\n * Google Drive's query syntax requires escaping special characters\n * in query strings. These utilities provide consistent escaping and\n * query construction for searching files and folders.\n */\n\n/**\n * Escape special characters for Google Drive query strings.\n * Escapes backslashes and single quotes which have special meaning in queries.\n */\nexport function escapeQueryString(text: string): string {\n return text.replace(/\\\\/g, \"\\\\\\\\\").replace(/'/g, \"\\\\'\");\n}\n\n/**\n * Build a name query for exact or partial match.\n *\n * @param name - The file/folder name to search for\n * @param exact - If true, uses exact match (=). If false, uses contains.\n * @returns Query string like \"name = 'escaped-name'\" or \"name contains 'escaped-name'\"\n */\nexport function buildNameQuery(name: string, exact = true): string {\n const escaped = escapeQueryString(name);\n return exact ? `name = '${escaped}'` : `name contains '${escaped}'`;\n}\n\n/**\n * Build a parent folder query.\n *\n * @param folderId - The parent folder ID\n * @returns Query string like \"'folderId' in parents\"\n */\nexport function buildParentQuery(folderId: string): string {\n return `'${folderId}' in parents`;\n}\n\n/**\n * Build a full text search query.\n *\n * @param searchText - The text to search for in file contents\n * @returns Query string like \"fullText contains 'escaped-text'\"\n */\nexport function buildFullTextQuery(searchText: string): string {\n const escaped = escapeQueryString(searchText);\n return `fullText contains '${escaped}'`;\n}\n\n/**\n * Build a MIME type filter query.\n *\n * @param mimeType - The MIME type to filter for\n * @returns Query string like \"mimeType = 'application/vnd.google-apps.folder'\"\n */\nexport function buildMimeTypeQuery(mimeType: string): string {\n return `mimeType = '${mimeType}'`;\n}\n\n/**\n * Combine multiple query conditions with AND.\n *\n * @param conditions - Array of query conditions\n * @returns Combined query string with \" and \" between conditions\n */\nexport function combineQueries(...conditions: string[]): string {\n return conditions.filter(Boolean).join(\" and \");\n}\n", "/**\n * Formatting utilities for file sizes and other values.\n */\n\n/**\n * Unit labels for byte formatting.\n */\nconst BYTE_UNITS = [\"B\", \"KB\", \"MB\", \"GB\", \"TB\"] as const;\n\n/**\n * Format bytes into human-readable string.\n *\n * @param bytes - The byte count (string, number, null, or undefined)\n * @param options - Formatting options\n * @param options.precision - Number of decimal places (default: 2)\n * @param options.nullValue - Value to return for null/undefined/NaN input (default: 'N/A')\n * @returns Formatted string like \"1.25 MB\" or \"N/A\"\n */\nexport function formatBytes(\n bytes: string | number | null | undefined,\n options: { precision?: number; nullValue?: string } = {},\n): string {\n const { precision = 2, nullValue = \"N/A\" } = options;\n\n // Handle null/undefined\n if (bytes === null || bytes === undefined) {\n return nullValue;\n }\n\n // Parse to number\n const num = typeof bytes === \"string\" ? parseInt(bytes, 10) : bytes;\n\n // Handle NaN or invalid\n if (isNaN(num)) {\n return nullValue;\n }\n\n // Handle zero\n if (num === 0) {\n return \"0 B\";\n }\n\n // Find appropriate unit\n let unitIndex = 0;\n let value = Math.abs(num);\n\n while (value >= 1024 && unitIndex < BYTE_UNITS.length - 1) {\n value /= 1024;\n unitIndex++;\n }\n\n // Preserve sign\n if (num < 0) {\n value = -value;\n }\n\n // Format with precision, but strip trailing zeros for whole numbers\n const formatted = value.toFixed(precision);\n return `${formatted} ${BYTE_UNITS[unitIndex]}`;\n}\n\n/**\n * Format bytes with a compact style (1 decimal place, B instead of bytes).\n * Useful for condensed displays like tables.\n *\n * @param bytes - The byte count\n * @param nullValue - Value to return for null/undefined input\n * @returns Formatted string like \"1.2 MB\" or \"N/A\"\n */\nexport function formatBytesCompact(\n bytes: string | number | null | undefined,\n nullValue = \"N/A\",\n): string {\n return formatBytes(bytes, { precision: 1, nullValue });\n}\n", "import { z } from \"zod\";\n\nexport const GetFolderTreeSchema = z\n .object({\n folderId: z.string().optional(),\n folderPath: z.string().optional(),\n depth: z.number().min(1).max(5).optional().default(2),\n })\n .refine((data) => !(data.folderId && data.folderPath), {\n message: \"Provide either folderId or folderPath, not both\",\n });\n\nexport type GetFolderTreeInput = z.infer<typeof GetFolderTreeSchema>;\n\nexport const SearchSchema = z.object({\n query: z.string().min(1, \"Search query is required\"),\n searchType: z\n .enum([\"fulltext\", \"name\", \"name_exact\"])\n .optional()\n .default(\"fulltext\")\n .describe(\n \"Search type: 'fulltext' (default, searches content), 'name' (filename contains), 'name_exact' (exact filename match)\",\n ),\n pageSize: z.number().int().min(1).max(100).optional(),\n pageToken: z.string().optional(),\n});\n\nexport const CreateTextFileSchema = z\n .object({\n name: z.string().min(1, \"File name is required\"),\n content: z.string(),\n parentFolderId: z.string().optional(),\n parentPath: z.string().optional(),\n })\n .refine((data) => !(data.parentFolderId && data.parentPath), {\n message: \"Provide either parentFolderId or parentPath, not both\",\n });\n\nexport const UpdateTextFileSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\"),\n content: z.string(),\n name: z.string().optional(),\n});\n\nexport const CreateFolderSchema = z\n .object({\n name: z.string().min(1, \"Folder name is required\"),\n parent: z.string().optional(),\n parentPath: z.string().optional(),\n })\n .refine((data) => !(data.parent && data.parentPath), {\n message: \"Provide either parent (folderId) or parentPath, not both\",\n });\n\nexport const ListFolderSchema = z.object({\n folderId: z.string().optional(),\n pageSize: z.number().int().min(1).max(100).optional(),\n pageToken: z.string().optional(),\n});\n\nexport const DeleteItemSchema = z.object({\n itemId: z.string().min(1, \"Item ID is required\"),\n});\n\nexport const RenameItemSchema = z.object({\n itemId: z.string().min(1, \"Item ID is required\"),\n newName: z.string().min(1, \"New name is required\"),\n});\n\nexport const MoveItemSchema = z\n .object({\n itemId: z.string().min(1, \"Item ID is required\"),\n destinationFolderId: z.string().optional(),\n destinationPath: z.string().optional(),\n })\n .refine((data) => !(data.destinationFolderId && data.destinationPath), {\n message: \"Provide either destinationFolderId or destinationPath, not both\",\n });\n\nexport const CopyFileSchema = z.object({\n sourceFileId: z.string().min(1, \"Source file ID is required\"),\n destinationName: z.string().optional(),\n destinationFolderId: z.string().optional(),\n});\n\nexport const GetFileMetadataSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\"),\n});\n\nexport const ExportFileSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\"),\n format: z.enum([\"pdf\", \"docx\", \"xlsx\", \"pptx\", \"csv\", \"tsv\", \"odt\", \"ods\", \"odp\"]),\n outputPath: z.string().optional(),\n});\n\n// Sharing schemas\nexport const ShareFileSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\"),\n role: z.enum([\"reader\", \"commenter\", \"writer\", \"organizer\"]),\n type: z.enum([\"user\", \"group\", \"domain\", \"anyone\"]),\n emailAddress: z.string().email().optional(),\n domain: z.string().optional(),\n sendNotificationEmail: z.boolean().optional().default(true),\n emailMessage: z.string().optional(),\n});\n\nexport const GetSharingSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\"),\n});\n\n// Revision schemas\nexport const ListRevisionsSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\"),\n pageSize: z.number().int().min(1).max(1000).optional(),\n});\n\nexport const RestoreRevisionSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\"),\n revisionId: z.string().min(1, \"Revision ID is required\"),\n});\n\n// Binary file schemas\nexport const DownloadFileSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\"),\n outputPath: z.string().optional(),\n});\n\nexport const UploadFileSchema = z\n .object({\n name: z.string().min(1, \"File name is required\"),\n sourcePath: z.string().optional(),\n base64Content: z.string().optional(),\n mimeType: z.string().optional(),\n folderId: z.string().optional(),\n folderPath: z.string().optional(),\n })\n .refine((data) => !(data.folderId && data.folderPath), {\n message: \"Provide either folderId or folderPath, not both\",\n });\n\n// Metadata schemas\nexport const GetStorageQuotaSchema = z.object({});\n\nexport const StarFileSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\"),\n starred: z.boolean(),\n});\n\n// File path resolution\nexport const ResolveFilePathSchema = z.object({\n path: z.string().min(1, \"Path is required\"),\n type: z.enum([\"file\", \"folder\", \"any\"]).optional().default(\"any\"),\n});\n\n// Batch operations\nexport const BatchDeleteSchema = z.object({\n fileIds: z\n .array(z.string())\n .min(1, \"At least one file ID required\")\n .max(100, \"Maximum 100 files per batch\"),\n});\n\nexport const BatchRestoreSchema = z.object({\n fileIds: z\n .array(z.string().min(1))\n .min(1, \"At least one file ID required\")\n .max(100, \"Maximum 100 files per batch\"),\n});\n\nexport const BatchMoveSchema = z\n .object({\n fileIds: z\n .array(z.string())\n .min(1, \"At least one file ID required\")\n .max(100, \"Maximum 100 files per batch\"),\n destinationFolderId: z.string().optional(),\n destinationPath: z.string().optional(),\n })\n .refine((data) => data.destinationFolderId || data.destinationPath, {\n message: \"Either destinationFolderId or destinationPath is required\",\n })\n .refine((data) => !(data.destinationFolderId && data.destinationPath), {\n message: \"Provide either destinationFolderId or destinationPath, not both\",\n });\n\nexport const BatchShareSchema = z.object({\n fileIds: z\n .array(z.string())\n .min(1, \"At least one file ID required\")\n .max(100, \"Maximum 100 files per batch\"),\n email: z.string().email(\"Valid email is required\"),\n role: z.enum([\"reader\", \"writer\", \"commenter\"]),\n sendNotification: z.boolean().optional().default(true),\n});\n\n// Permission management\nexport const RemovePermissionSchema = z\n .object({\n fileId: z.string().min(1, \"File ID is required\"),\n permissionId: z.string().optional(),\n email: z.string().email().optional(),\n })\n .refine((data) => data.permissionId || data.email, {\n message: \"Either permissionId or email is required\",\n });\n\n// Trash management\nexport const ListTrashSchema = z.object({\n pageSize: z.number().int().min(1).max(100).optional().default(50),\n pageToken: z.string().optional(),\n});\n\nexport const RestoreFromTrashSchema = z\n .object({\n fileId: z.string().min(1, \"File ID is required\"),\n destinationFolderId: z.string().optional(),\n destinationPath: z.string().optional(),\n })\n .refine((data) => !(data.destinationFolderId && data.destinationPath), {\n message: \"Provide either destinationFolderId or destinationPath, not both\",\n });\n\nexport const EmptyTrashSchema = z.object({\n confirm: z.literal(true, {\n message: \"Must set confirm: true to empty trash\",\n }),\n driveId: z.string().optional(),\n});\n\n// Type exports\nexport type SearchInput = z.infer<typeof SearchSchema>;\nexport type CreateTextFileInput = z.infer<typeof CreateTextFileSchema>;\nexport type UpdateTextFileInput = z.infer<typeof UpdateTextFileSchema>;\nexport type CreateFolderInput = z.infer<typeof CreateFolderSchema>;\nexport type ListFolderInput = z.infer<typeof ListFolderSchema>;\nexport type DeleteItemInput = z.infer<typeof DeleteItemSchema>;\nexport type RenameItemInput = z.infer<typeof RenameItemSchema>;\nexport type MoveItemInput = z.infer<typeof MoveItemSchema>;\nexport type CopyFileInput = z.infer<typeof CopyFileSchema>;\nexport type GetFileMetadataInput = z.infer<typeof GetFileMetadataSchema>;\nexport type ExportFileInput = z.infer<typeof ExportFileSchema>;\nexport type ShareFileInput = z.infer<typeof ShareFileSchema>;\nexport type GetSharingInput = z.infer<typeof GetSharingSchema>;\nexport type ListRevisionsInput = z.infer<typeof ListRevisionsSchema>;\nexport type RestoreRevisionInput = z.infer<typeof RestoreRevisionSchema>;\nexport type DownloadFileInput = z.infer<typeof DownloadFileSchema>;\nexport type UploadFileInput = z.infer<typeof UploadFileSchema>;\nexport type GetStorageQuotaInput = z.infer<typeof GetStorageQuotaSchema>;\nexport type StarFileInput = z.infer<typeof StarFileSchema>;\nexport type ResolveFilePathInput = z.infer<typeof ResolveFilePathSchema>;\nexport type BatchDeleteInput = z.infer<typeof BatchDeleteSchema>;\nexport type BatchRestoreInput = z.infer<typeof BatchRestoreSchema>;\nexport type BatchMoveInput = z.infer<typeof BatchMoveSchema>;\nexport type BatchShareInput = z.infer<typeof BatchShareSchema>;\nexport type RemovePermissionInput = z.infer<typeof RemovePermissionSchema>;\nexport type ListTrashInput = z.infer<typeof ListTrashSchema>;\nexport type RestoreFromTrashInput = z.infer<typeof RestoreFromTrashSchema>;\nexport type EmptyTrashInput = z.infer<typeof EmptyTrashSchema>;\n", "import { z } from \"zod\";\n\nexport const CreateGoogleDocSchema = z\n .object({\n name: z.string().min(1, \"Document name is required\"),\n content: z.string(),\n parentFolderId: z.string().optional(),\n parentPath: z.string().optional(),\n })\n .refine((data) => !(data.parentFolderId && data.parentPath), {\n message: \"Provide either parentFolderId or parentPath, not both\",\n });\n\nexport const UpdateGoogleDocSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n content: z.string(),\n});\n\nexport const GetGoogleDocContentSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n});\n\nexport const AppendToDocSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n text: z.string().min(1, \"Text is required\"),\n insertNewline: z.boolean().optional().default(true),\n});\n\nexport const InsertTextInDocSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n text: z.string().min(1, \"Text is required\"),\n index: z.number().int().min(1, \"Index must be >= 1 (1 = beginning of document content)\"),\n});\n\nexport const DeleteTextInDocSchema = z\n .object({\n documentId: z.string().min(1, \"Document ID is required\"),\n startIndex: z.number().int().min(1, \"Start index must be >= 1\"),\n endIndex: z.number().int().min(2, \"End index must be >= 2\"),\n })\n .refine((data) => data.endIndex > data.startIndex, {\n message: \"endIndex must be greater than startIndex\",\n });\n\nexport const ReplaceTextInDocSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n searchText: z.string().min(1, \"Search text is required\"),\n replaceText: z.string(),\n matchCase: z.boolean().optional().default(true),\n});\n\nexport const FormatGoogleDocRangeSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n startIndex: z.number().min(1, \"Start index must be at least 1\").optional(),\n endIndex: z.number().min(1, \"End index must be at least 1\").optional(),\n\n // Text formatting\n bold: z.boolean().optional(),\n italic: z.boolean().optional(),\n underline: z.boolean().optional(),\n strikethrough: z.boolean().optional(),\n fontSize: z.number().optional(),\n fontFamily: z.string().optional(),\n foregroundColor: z\n .object({\n red: z.number().min(0).max(1).optional(),\n green: z.number().min(0).max(1).optional(),\n blue: z.number().min(0).max(1).optional(),\n })\n .optional(),\n\n // Paragraph formatting\n alignment: z.enum([\"START\", \"CENTER\", \"END\", \"JUSTIFIED\"]).optional(),\n lineSpacing: z.number().optional(),\n spaceAbove: z.number().optional(),\n spaceBelow: z.number().optional(),\n namedStyleType: z\n .enum([\n \"NORMAL_TEXT\",\n \"TITLE\",\n \"SUBTITLE\",\n \"HEADING_1\",\n \"HEADING_2\",\n \"HEADING_3\",\n \"HEADING_4\",\n \"HEADING_5\",\n \"HEADING_6\",\n ])\n .optional(),\n});\n\n// Type exports\nexport type CreateGoogleDocInput = z.infer<typeof CreateGoogleDocSchema>;\nexport type UpdateGoogleDocInput = z.infer<typeof UpdateGoogleDocSchema>;\nexport type GetGoogleDocContentInput = z.infer<typeof GetGoogleDocContentSchema>;\nexport type AppendToDocInput = z.infer<typeof AppendToDocSchema>;\nexport type InsertTextInDocInput = z.infer<typeof InsertTextInDocSchema>;\nexport type DeleteTextInDocInput = z.infer<typeof DeleteTextInDocSchema>;\nexport type ReplaceTextInDocInput = z.infer<typeof ReplaceTextInDocSchema>;\nexport type FormatGoogleDocRangeInput = z.infer<typeof FormatGoogleDocRangeSchema>;\n", "import { z } from \"zod\";\n\n// Unified sheet tabs schema - replaces list/create/delete/rename individual schemas\nexport const SheetTabsSchema = z\n .object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n action: z.enum([\"list\", \"create\", \"delete\", \"rename\"]),\n title: z.string().optional().describe(\"Tab title (for create/delete)\"),\n index: z.number().int().min(0).optional().describe(\"Position for new tab (create only)\"),\n currentTitle: z.string().optional().describe(\"Current title to rename (rename only)\"),\n newTitle: z.string().optional().describe(\"New title (rename only)\"),\n })\n .refine(\n (data) => {\n switch (data.action) {\n case \"list\":\n return true;\n case \"create\":\n case \"delete\":\n return !!data.title;\n case \"rename\":\n return !!(data.currentTitle && data.newTitle);\n default:\n return false;\n }\n },\n {\n message:\n \"Missing required params: create/delete need 'title', rename needs 'currentTitle' and 'newTitle'\",\n },\n );\n\nexport type SheetTabsInput = z.infer<typeof SheetTabsSchema>;\n\nexport const CreateGoogleSheetSchema = z\n .object({\n name: z.string().min(1, \"Sheet name is required\"),\n data: z.array(z.array(z.string())),\n parentFolderId: z.string().optional(),\n parentPath: z.string().optional(),\n valueInputOption: z.enum([\"RAW\", \"USER_ENTERED\"]).optional(),\n })\n .refine((data) => !(data.parentFolderId && data.parentPath), {\n message: \"Provide either parentFolderId or parentPath, not both\",\n });\n\nexport const UpdateGoogleSheetSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n range: z.string().min(1, \"Range is required\"),\n data: z.array(z.array(z.string())),\n valueInputOption: z.enum([\"RAW\", \"USER_ENTERED\"]).optional(),\n});\n\nexport const GetGoogleSheetContentSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n range: z.string().optional(),\n});\n\n// Color schema reused across formatting options\nconst ColorSchema = z.object({\n red: z.number().min(0).max(1).optional(),\n green: z.number().min(0).max(1).optional(),\n blue: z.number().min(0).max(1).optional(),\n});\n\nexport const FormatGoogleSheetCellsSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n range: z.string().min(1, \"Range is required\"),\n // Cell formatting\n backgroundColor: ColorSchema.optional(),\n horizontalAlignment: z.enum([\"LEFT\", \"CENTER\", \"RIGHT\"]).optional(),\n verticalAlignment: z.enum([\"TOP\", \"MIDDLE\", \"BOTTOM\"]).optional(),\n wrapStrategy: z.enum([\"OVERFLOW_CELL\", \"CLIP\", \"WRAP\"]).optional(),\n // Text formatting\n bold: z.boolean().optional(),\n italic: z.boolean().optional(),\n strikethrough: z.boolean().optional(),\n underline: z.boolean().optional(),\n fontSize: z.number().min(1).optional(),\n fontFamily: z.string().optional(),\n foregroundColor: ColorSchema.optional(),\n // Number formatting\n numberFormat: z\n .object({\n pattern: z.string(),\n type: z\n .enum([\"NUMBER\", \"CURRENCY\", \"PERCENT\", \"DATE\", \"TIME\", \"DATE_TIME\", \"SCIENTIFIC\"])\n .optional(),\n })\n .optional(),\n // Border formatting\n borders: z\n .object({\n style: z.enum([\"SOLID\", \"DASHED\", \"DOTTED\", \"DOUBLE\"]),\n width: z.number().min(1).max(3).optional(),\n color: ColorSchema.optional(),\n top: z.boolean().optional(),\n bottom: z.boolean().optional(),\n left: z.boolean().optional(),\n right: z.boolean().optional(),\n innerHorizontal: z.boolean().optional(),\n innerVertical: z.boolean().optional(),\n })\n .optional(),\n});\n\nexport const MergeGoogleSheetCellsSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n range: z.string().min(1, \"Range is required\"),\n mergeType: z.enum([\"MERGE_ALL\", \"MERGE_COLUMNS\", \"MERGE_ROWS\"]),\n});\n\nexport const AddGoogleSheetConditionalFormatSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n range: z.string().min(1, \"Range is required\"),\n condition: z.object({\n type: z.enum([\n \"NUMBER_GREATER\",\n \"NUMBER_LESS\",\n \"TEXT_CONTAINS\",\n \"TEXT_STARTS_WITH\",\n \"TEXT_ENDS_WITH\",\n \"CUSTOM_FORMULA\",\n ]),\n value: z.string(),\n }),\n format: z.object({\n backgroundColor: z\n .object({\n red: z.number().min(0).max(1).optional(),\n green: z.number().min(0).max(1).optional(),\n blue: z.number().min(0).max(1).optional(),\n })\n .optional(),\n textFormat: z\n .object({\n bold: z.boolean().optional(),\n foregroundColor: z\n .object({\n red: z.number().min(0).max(1).optional(),\n green: z.number().min(0).max(1).optional(),\n blue: z.number().min(0).max(1).optional(),\n })\n .optional(),\n })\n .optional(),\n }),\n});\n\n// Type exports\nexport type CreateGoogleSheetInput = z.infer<typeof CreateGoogleSheetSchema>;\nexport type UpdateGoogleSheetInput = z.infer<typeof UpdateGoogleSheetSchema>;\nexport type GetGoogleSheetContentInput = z.infer<typeof GetGoogleSheetContentSchema>;\nexport type FormatGoogleSheetCellsInput = z.infer<typeof FormatGoogleSheetCellsSchema>;\nexport type MergeGoogleSheetCellsInput = z.infer<typeof MergeGoogleSheetCellsSchema>;\nexport type AddGoogleSheetConditionalFormatInput = z.infer<\n typeof AddGoogleSheetConditionalFormatSchema\n>;\n", "import { z } from \"zod\";\n\n// Reusable color schemas\nconst ColorSchema = z.object({\n red: z.number().min(0).max(1).optional(),\n green: z.number().min(0).max(1).optional(),\n blue: z.number().min(0).max(1).optional(),\n});\n\nconst ColorWithAlphaSchema = ColorSchema.extend({\n alpha: z.number().min(0).max(1).optional(),\n});\n\nexport const ListSlidePagesSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n});\n\nexport type ListSlidePagesInput = z.infer<typeof ListSlidePagesSchema>;\n\nexport const CreateGoogleSlidesSchema = z\n .object({\n name: z.string().min(1, \"Presentation name is required\"),\n slides: z\n .array(\n z.object({\n title: z.string(),\n content: z.string(),\n }),\n )\n .min(1, \"At least one slide is required\"),\n parentFolderId: z.string().optional(),\n parentPath: z.string().optional(),\n })\n .refine((data) => !(data.parentFolderId && data.parentPath), {\n message: \"Provide either parentFolderId or parentPath, not both\",\n });\n\nexport const UpdateGoogleSlidesSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n slides: z\n .array(\n z.object({\n title: z.string(),\n content: z.string(),\n }),\n )\n .min(1, \"At least one slide is required\"),\n});\n\nexport const GetGoogleSlidesContentSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n slideIndex: z.number().min(0).optional(),\n});\n\nexport const CreateGoogleSlidesTextBoxSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n pageObjectId: z.string().min(1, \"Page object ID is required\"),\n text: z.string().min(1, \"Text content is required\"),\n x: z.number(),\n y: z.number(),\n width: z.number(),\n height: z.number(),\n fontSize: z.number().optional(),\n bold: z.boolean().optional(),\n italic: z.boolean().optional(),\n});\n\nexport const CreateGoogleSlidesShapeSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n pageObjectId: z.string().min(1, \"Page object ID is required\"),\n shapeType: z.enum([\n \"RECTANGLE\",\n \"ELLIPSE\",\n \"DIAMOND\",\n \"TRIANGLE\",\n \"STAR\",\n \"ROUND_RECTANGLE\",\n \"ARROW\",\n ]),\n x: z.number(),\n y: z.number(),\n width: z.number(),\n height: z.number(),\n backgroundColor: z\n .object({\n red: z.number().min(0).max(1).optional(),\n green: z.number().min(0).max(1).optional(),\n blue: z.number().min(0).max(1).optional(),\n alpha: z.number().min(0).max(1).optional(),\n })\n .optional(),\n});\n\n// Unified speaker notes schema - replaces get/update individual schemas\nexport const SlidesSpeakerNotesSchema = z\n .object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n slideIndex: z.number().min(0, \"Slide index must be non-negative\"),\n action: z.enum([\"get\", \"update\"]),\n notes: z.string().optional().describe(\"Notes content (required for update)\"),\n })\n .refine(\n (data) => {\n if (data.action === \"update\") return data.notes !== undefined;\n return true;\n },\n { message: \"notes is required for update action\" },\n );\n\nexport type SlidesSpeakerNotesInput = z.infer<typeof SlidesSpeakerNotesSchema>;\n\n// Focused text formatting schema\nexport const FormatSlidesTextSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n objectId: z.string().min(1, \"Object ID is required\"),\n\n // Text range (optional - defaults to all text)\n startIndex: z.number().min(0).optional(),\n endIndex: z.number().min(0).optional(),\n\n // Character formatting\n bold: z.boolean().optional(),\n italic: z.boolean().optional(),\n underline: z.boolean().optional(),\n strikethrough: z.boolean().optional(),\n fontSize: z.number().optional(),\n fontFamily: z.string().optional(),\n foregroundColor: ColorSchema.optional(),\n\n // Paragraph formatting\n alignment: z.enum([\"START\", \"CENTER\", \"END\", \"JUSTIFIED\"]).optional(),\n lineSpacing: z.number().optional(),\n bulletStyle: z\n .enum([\"NONE\", \"DISC\", \"ARROW\", \"SQUARE\", \"DIAMOND\", \"STAR\", \"NUMBERED\"])\n .optional(),\n});\n\n// Focused shape styling schema\nexport const FormatSlidesShapeSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n objectId: z.string().min(1, \"Object ID is required\"),\n\n // Shape fill\n backgroundColor: ColorWithAlphaSchema.optional(),\n\n // Outline styling\n outlineColor: ColorSchema.optional(),\n outlineWeight: z.number().optional(),\n outlineDashStyle: z\n .enum([\"SOLID\", \"DOT\", \"DASH\", \"DASH_DOT\", \"LONG_DASH\", \"LONG_DASH_DOT\"])\n .optional(),\n});\n\n// Focused slide background schema\nexport const FormatSlideBackgroundSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n pageObjectIds: z.array(z.string().min(1)).min(1, \"At least one slide ID is required\"),\n backgroundColor: ColorWithAlphaSchema,\n});\n\n// Type exports\nexport type CreateGoogleSlidesInput = z.infer<typeof CreateGoogleSlidesSchema>;\nexport type UpdateGoogleSlidesInput = z.infer<typeof UpdateGoogleSlidesSchema>;\nexport type GetGoogleSlidesContentInput = z.infer<typeof GetGoogleSlidesContentSchema>;\nexport type CreateGoogleSlidesTextBoxInput = z.infer<typeof CreateGoogleSlidesTextBoxSchema>;\nexport type CreateGoogleSlidesShapeInput = z.infer<typeof CreateGoogleSlidesShapeSchema>;\nexport type FormatSlidesTextInput = z.infer<typeof FormatSlidesTextSchema>;\nexport type FormatSlidesShapeInput = z.infer<typeof FormatSlidesShapeSchema>;\nexport type FormatSlideBackgroundInput = z.infer<typeof FormatSlideBackgroundSchema>;\n", "import { z } from \"zod\";\n\n/**\n * Smart file creation that infers type from name/content.\n * Routes to appropriate Google Workspace type based on extension or explicit type.\n */\nexport const CreateFileSchema = z\n .object({\n name: z.string().min(1, \"File name is required\"),\n content: z.union([\n z.string(),\n z.array(z.array(z.string())), // 2D array for sheets\n z.array(\n z.object({\n // Slides array\n title: z.string(),\n content: z.string(),\n }),\n ),\n ]),\n parentFolderId: z.string().optional(),\n parentPath: z.string().optional(),\n type: z.enum([\"doc\", \"sheet\", \"slides\", \"text\"]).optional(),\n })\n .refine((data) => !(data.parentFolderId && data.parentPath), {\n message: \"Provide either parentFolderId or parentPath, not both\",\n });\n\nexport type CreateFileInput = z.infer<typeof CreateFileSchema>;\n\n/**\n * Smart file update that detects file type from ID.\n * Routes to appropriate update handler based on file's mimeType.\n */\nexport const UpdateFileSchema = z\n .object({\n fileId: z.string().optional(),\n filePath: z.string().optional(),\n content: z.union([\n z.string(),\n z.array(z.array(z.string())), // 2D array for sheets\n z.array(\n z.object({\n // Slides array\n title: z.string(),\n content: z.string(),\n }),\n ),\n ]),\n range: z.string().optional(), // For sheets: \"Sheet1!A1:C10\"\n })\n .refine((data) => data.fileId || data.filePath, {\n message: \"Either fileId or filePath must be provided\",\n })\n .refine((data) => !(data.fileId && data.filePath), {\n message: \"Provide either fileId or filePath, not both\",\n });\n\nexport type UpdateFileInput = z.infer<typeof UpdateFileSchema>;\n\n/**\n * Smart content retrieval that detects file type.\n * Returns structured content for Sheets/Slides, text for Docs/text files.\n */\nexport const GetFileContentSchema = z\n .object({\n fileId: z.string().optional(),\n filePath: z.string().optional(),\n range: z.string().optional(), // For sheets: \"Sheet1!A1:C10\"\n })\n .refine((data) => data.fileId || data.filePath, {\n message: \"Either fileId or filePath must be provided\",\n })\n .refine((data) => !(data.fileId && data.filePath), {\n message: \"Provide either fileId or filePath, not both\",\n });\n\nexport type GetFileContentInput = z.infer<typeof GetFileContentSchema>;\n", "import { z } from \"zod\";\n\n// Shared schemas for Calendar\n\n/**\n * EventDateTime - for specifying timed or all-day events.\n * Must have either dateTime (for timed events) or date (for all-day events), not both.\n */\nexport const EventDateTimeSchema = z\n .object({\n dateTime: z\n .string()\n .optional()\n .describe(\"RFC3339 timestamp with timezone offset (e.g., 2024-01-15T09:00:00-05:00)\"),\n date: z\n .string()\n .optional()\n .describe(\"Date for all-day events (YYYY-MM-DD format, e.g., 2024-01-15)\"),\n timeZone: z.string().optional().describe(\"IANA timezone (e.g., America/New_York)\"),\n })\n .refine((data) => data.dateTime || data.date, {\n message: \"Either dateTime or date is required\",\n })\n .refine((data) => !(data.dateTime && data.date), {\n message: \"Cannot have both dateTime and date - use dateTime for timed events, date for all-day\",\n });\n\nexport type EventDateTimeInput = z.infer<typeof EventDateTimeSchema>;\n\n/**\n * Attendee schema for event invites\n */\nexport const AttendeeSchema = z.object({\n email: z.string().email(\"Valid email required\"),\n displayName: z.string().optional(),\n optional: z.boolean().optional().describe(\"Whether attendance is optional\"),\n responseStatus: z\n .enum([\"needsAction\", \"declined\", \"tentative\", \"accepted\"])\n .optional()\n .describe(\"Attendee's response status\"),\n});\n\nexport type AttendeeInput = z.infer<typeof AttendeeSchema>;\n\n/**\n * Reminder schema for event notifications\n */\nexport const ReminderSchema = z.object({\n method: z.enum([\"email\", \"popup\"]).describe(\"Reminder delivery method\"),\n minutes: z.number().min(0).max(40320).describe(\"Minutes before event (max 4 weeks)\"),\n});\n\nexport type ReminderInput = z.infer<typeof ReminderSchema>;\n\n// Tool-specific schemas\n\nexport const ListCalendarsSchema = z.object({\n showHidden: z.boolean().optional().default(false).describe(\"Include hidden calendars\"),\n showDeleted: z.boolean().optional().default(false).describe(\"Include deleted calendars\"),\n});\n\nexport type ListCalendarsInput = z.infer<typeof ListCalendarsSchema>;\n\nexport const ListEventsSchema = z.object({\n calendarId: z\n .string()\n .optional()\n .default(\"primary\")\n .describe(\"Calendar ID (defaults to primary calendar)\"),\n timeMin: z.string().optional().describe(\"Lower bound for event start time (RFC3339 timestamp)\"),\n timeMax: z.string().optional().describe(\"Upper bound for event start time (RFC3339 timestamp)\"),\n query: z.string().optional().describe(\"Free text search terms\"),\n maxResults: z.number().int().min(1).max(2500).optional().default(250).describe(\"Max events\"),\n pageToken: z.string().optional().describe(\"Token for pagination\"),\n singleEvents: z\n .boolean()\n .optional()\n .default(true)\n .describe(\"Expand recurring events into instances\"),\n orderBy: z\n .enum([\"startTime\", \"updated\"])\n .optional()\n .default(\"startTime\")\n .describe(\"Sort order (startTime requires singleEvents=true)\"),\n});\n\nexport type ListEventsInput = z.infer<typeof ListEventsSchema>;\n\nexport const GetEventSchema = z.object({\n calendarId: z.string().optional().default(\"primary\").describe(\"Calendar ID\"),\n eventId: z.string().min(1, \"Event ID is required\"),\n});\n\nexport type GetEventInput = z.infer<typeof GetEventSchema>;\n\nexport const CreateEventSchema = z.object({\n calendarId: z.string().optional().default(\"primary\").describe(\"Calendar ID\"),\n summary: z.string().min(1, \"Event title is required\"),\n description: z.string().optional().describe(\"Event description\"),\n location: z.string().optional().describe(\"Event location\"),\n start: EventDateTimeSchema.describe(\"Event start time\"),\n end: EventDateTimeSchema.describe(\"Event end time\"),\n attendees: z.array(AttendeeSchema).optional().describe(\"List of attendees\"),\n addGoogleMeet: z.boolean().optional().default(false).describe(\"Add Google Meet video conference\"),\n reminders: z.array(ReminderSchema).optional().describe(\"Custom reminders (overrides defaults)\"),\n colorId: z\n .string()\n .optional()\n .describe(\"Event color ID (1-11, see Google Calendar color palette)\"),\n recurrence: z\n .array(z.string())\n .optional()\n .describe(\"RRULE strings for recurring events (e.g., RRULE:FREQ=WEEKLY;COUNT=10)\"),\n sendUpdates: z\n .enum([\"all\", \"externalOnly\", \"none\"])\n .optional()\n .default(\"all\")\n .describe(\"Who to send notifications to\"),\n});\n\nexport type CreateEventInput = z.infer<typeof CreateEventSchema>;\n\nexport const UpdateEventSchema = z.object({\n calendarId: z.string().optional().default(\"primary\").describe(\"Calendar ID\"),\n eventId: z.string().min(1, \"Event ID is required\"),\n summary: z.string().optional().describe(\"Event title\"),\n description: z.string().optional().describe(\"Event description\"),\n location: z.string().optional().describe(\"Event location\"),\n start: EventDateTimeSchema.optional().describe(\"Event start time\"),\n end: EventDateTimeSchema.optional().describe(\"Event end time\"),\n attendees: z.array(AttendeeSchema).optional().describe(\"Replace attendee list\"),\n addGoogleMeet: z.boolean().optional().describe(\"Add Google Meet video conference\"),\n reminders: z.array(ReminderSchema).optional().describe(\"Custom reminders\"),\n colorId: z.string().optional().describe(\"Event color ID (1-11)\"),\n sendUpdates: z\n .enum([\"all\", \"externalOnly\", \"none\"])\n .optional()\n .default(\"all\")\n .describe(\"Who to send notifications to\"),\n});\n\nexport type UpdateEventInput = z.infer<typeof UpdateEventSchema>;\n\nexport const DeleteEventSchema = z.object({\n calendarId: z.string().optional().default(\"primary\").describe(\"Calendar ID\"),\n eventId: z.string().min(1, \"Event ID is required\"),\n sendUpdates: z\n .enum([\"all\", \"externalOnly\", \"none\"])\n .optional()\n .default(\"all\")\n .describe(\"Who to send cancellation notices to\"),\n});\n\nexport type DeleteEventInput = z.infer<typeof DeleteEventSchema>;\n\nexport const FindFreeTimeSchema = z.object({\n calendarIds: z\n .array(z.string())\n .min(1, \"At least one calendar ID required\")\n .max(50, \"Maximum 50 calendars\")\n .describe(\"Calendar IDs to check for availability\"),\n timeMin: z.string().describe(\"Start of search range (RFC3339 timestamp)\"),\n timeMax: z.string().describe(\"End of search range (RFC3339 timestamp)\"),\n duration: z.number().int().min(1).describe(\"Required slot duration in minutes\"),\n timeZone: z.string().optional().default(\"UTC\").describe(\"Timezone for results\"),\n});\n\nexport type FindFreeTimeInput = z.infer<typeof FindFreeTimeSchema>;\n", "import { z } from \"zod\";\n\n/**\n * Gmail's allowed label colors (restricted palette)\n * @see https://developers.google.com/gmail/api/reference/rest/v1/users.labels\n */\nexport const GMAIL_LABEL_COLORS = [\n \"#000000\",\n \"#434343\",\n \"#666666\",\n \"#999999\",\n \"#cccccc\",\n \"#efefef\",\n \"#f3f3f3\",\n \"#ffffff\",\n \"#fb4c2f\",\n \"#ffad47\",\n \"#fad165\",\n \"#16a766\",\n \"#43d692\",\n \"#4a86e8\",\n \"#a479e2\",\n \"#f691b3\",\n \"#f6c5be\",\n \"#ffe6c7\",\n \"#fef1d1\",\n \"#b9e4d0\",\n \"#c6f3de\",\n \"#c9daf8\",\n \"#e4d7f5\",\n \"#fcdee8\",\n \"#efa093\",\n \"#ffd6a2\",\n \"#fce8b3\",\n \"#89d3b2\",\n \"#a0eac9\",\n \"#a4c2f4\",\n \"#d0bcf1\",\n \"#fbc8d9\",\n \"#e66550\",\n \"#ffbc6b\",\n \"#fcda83\",\n \"#5dc28c\",\n \"#74db9b\",\n \"#6d9eeb\",\n \"#b694e8\",\n \"#f7a7c0\",\n \"#cc3a21\",\n \"#eaa041\",\n \"#f2c960\",\n \"#149e60\",\n \"#44b984\",\n \"#3c78d8\",\n \"#8e63ce\",\n \"#e07798\",\n \"#ac2b16\",\n \"#cf8933\",\n \"#d5ae49\",\n \"#0b804b\",\n \"#339966\",\n \"#285bac\",\n \"#653e9b\",\n \"#b65775\",\n \"#822111\",\n \"#a46a21\",\n \"#aa8831\",\n \"#076239\",\n \"#1a764d\",\n \"#1c4587\",\n \"#41236d\",\n \"#83334c\",\n] as const;\n\nexport type GmailLabelColor = (typeof GMAIL_LABEL_COLORS)[number];\n\n/**\n * Schema for validating Gmail label colors (case-insensitive)\n */\nconst gmailLabelColorSchema = z\n .string()\n .refine((color) => GMAIL_LABEL_COLORS.includes(color.toLowerCase() as GmailLabelColor), {\n message: `Invalid Gmail label color. Must be one of: ${GMAIL_LABEL_COLORS.slice(0, 8).join(\", \")}... (see GMAIL_LABEL_COLORS for full list)`,\n })\n .transform((color) => color.toLowerCase());\n\n// Shared schemas\n\n/**\n * Email address with optional display name\n */\nexport const EmailAddressSchema = z.object({\n email: z.string().email(\"Valid email required\"),\n name: z.string().optional().describe(\"Display name\"),\n});\n\nexport type EmailAddressInput = z.infer<typeof EmailAddressSchema>;\n\n/**\n * Attachment for sending emails\n */\nexport const AttachmentSchema = z.object({\n filename: z.string().min(1, \"Filename required\"),\n content: z.string().describe(\"Base64-encoded content\"),\n mimeType: z.string().optional().describe(\"MIME type (auto-detected if not provided)\"),\n});\n\nexport type AttachmentInput = z.infer<typeof AttachmentSchema>;\n\n// Core Email Operations\n\nexport const SendEmailSchema = z.object({\n to: z.array(z.string().email()).min(1, \"At least one recipient required\"),\n subject: z.string().min(1, \"Subject required\"),\n body: z.string().describe(\"Plain text email body\"),\n html: z.string().optional().describe(\"HTML email body (overrides plain text for HTML clients)\"),\n cc: z.array(z.string().email()).optional().describe(\"CC recipients\"),\n bcc: z.array(z.string().email()).optional().describe(\"BCC recipients\"),\n replyTo: z.string().email().optional().describe(\"Reply-to address\"),\n attachments: z.array(AttachmentSchema).optional().describe(\"File attachments\"),\n threadId: z.string().optional().describe(\"Thread ID to reply to\"),\n inReplyTo: z.string().optional().describe(\"Message-ID header for threading\"),\n});\n\nexport type SendEmailInput = z.infer<typeof SendEmailSchema>;\n\nexport const DraftEmailSchema = z.object({\n to: z.array(z.string().email()).optional().describe(\"Recipients (can be empty for drafts)\"),\n subject: z.string().optional().describe(\"Subject (can be empty for drafts)\"),\n body: z.string().optional().describe(\"Plain text email body\"),\n html: z.string().optional().describe(\"HTML email body\"),\n cc: z.array(z.string().email()).optional().describe(\"CC recipients\"),\n bcc: z.array(z.string().email()).optional().describe(\"BCC recipients\"),\n replyTo: z.string().email().optional().describe(\"Reply-to address\"),\n attachments: z.array(AttachmentSchema).optional().describe(\"File attachments\"),\n threadId: z.string().optional().describe(\"Thread ID for draft replies\"),\n});\n\nexport type DraftEmailInput = z.infer<typeof DraftEmailSchema>;\n\nexport const ReadEmailSchema = z.object({\n messageId: z.string().min(1, \"Message ID required\"),\n format: z\n .enum([\"full\", \"metadata\", \"minimal\", \"raw\"])\n .optional()\n .default(\"full\")\n .describe(\"Response format\"),\n contentFormat: z\n .enum([\"full\", \"text\", \"headers\"])\n .optional()\n .default(\"full\")\n .describe(\"Content format: 'full' (text+HTML), 'text' (plain text only), 'headers' (no body)\"),\n});\n\nexport type ReadEmailInput = z.infer<typeof ReadEmailSchema>;\n\nexport const SearchEmailsSchema = z.object({\n query: z\n .string()\n .min(1, \"Search query required\")\n .describe(\"Gmail search query (e.g., 'from:sender@example.com', 'is:unread', 'subject:hello')\"),\n maxResults: z.number().int().min(1).max(500).optional().default(50).describe(\"Maximum results\"),\n pageToken: z.string().optional().describe(\"Token for pagination\"),\n labelIds: z.array(z.string()).optional().describe(\"Filter by label IDs\"),\n includeSpamTrash: z.boolean().optional().default(false).describe(\"Include spam and trash\"),\n});\n\nexport type SearchEmailsInput = z.infer<typeof SearchEmailsSchema>;\n\n/**\n * Schema for deleting emails - supports single ID or array for batch operations\n */\nexport const DeleteEmailSchema = z.object({\n messageId: z\n .union([z.string().min(1), z.array(z.string().min(1)).min(1).max(1000)])\n .describe(\"Message ID or array of IDs (max 1000 for batch)\"),\n});\n\nexport type DeleteEmailInput = z.infer<typeof DeleteEmailSchema>;\n\n/**\n * Schema for modifying email labels - supports single ID or array for batch operations\n */\nexport const ModifyEmailSchema = z.object({\n messageId: z\n .union([z.string().min(1), z.array(z.string().min(1)).min(1).max(1000)])\n .describe(\"Message ID or array of IDs (max 1000 for batch)\"),\n addLabelIds: z.array(z.string()).optional().describe(\"Label IDs to add\"),\n removeLabelIds: z.array(z.string()).optional().describe(\"Label IDs to remove\"),\n});\n\nexport type ModifyEmailInput = z.infer<typeof ModifyEmailSchema>;\n\nexport const DownloadAttachmentSchema = z.object({\n messageId: z.string().min(1, \"Message ID required\"),\n attachmentId: z.string().min(1, \"Attachment ID required\"),\n filename: z.string().optional().describe(\"Save filename (uses original if not specified)\"),\n outputPath: z.string().optional().describe(\"Output directory path\"),\n});\n\nexport type DownloadAttachmentInput = z.infer<typeof DownloadAttachmentSchema>;\n\n// Label Management\n\nexport const CreateLabelSchema = z.object({\n name: z.string().min(1, \"Label name required\"),\n messageListVisibility: z\n .enum([\"show\", \"hide\"])\n .optional()\n .default(\"show\")\n .describe(\"Show/hide in message list\"),\n labelListVisibility: z\n .enum([\"labelShow\", \"labelShowIfUnread\", \"labelHide\"])\n .optional()\n .default(\"labelShow\")\n .describe(\"Show/hide in label list\"),\n backgroundColor: gmailLabelColorSchema\n .optional()\n .describe(\"Background color from Gmail palette (e.g., #fb4c2f)\"),\n textColor: gmailLabelColorSchema\n .optional()\n .describe(\"Text color from Gmail palette (e.g., #ffffff)\"),\n});\n\nexport type CreateLabelInput = z.infer<typeof CreateLabelSchema>;\n\nexport const UpdateLabelSchema = z.object({\n labelId: z.string().min(1, \"Label ID required\"),\n name: z.string().optional().describe(\"New label name\"),\n messageListVisibility: z.enum([\"show\", \"hide\"]).optional(),\n labelListVisibility: z.enum([\"labelShow\", \"labelShowIfUnread\", \"labelHide\"]).optional(),\n backgroundColor: gmailLabelColorSchema.optional().describe(\"Background color from Gmail palette\"),\n textColor: gmailLabelColorSchema.optional().describe(\"Text color from Gmail palette\"),\n});\n\nexport type UpdateLabelInput = z.infer<typeof UpdateLabelSchema>;\n\nexport const DeleteLabelSchema = z.object({\n labelId: z.string().min(1, \"Label ID required\"),\n});\n\nexport type DeleteLabelInput = z.infer<typeof DeleteLabelSchema>;\n\nexport const ListLabelsSchema = z.object({\n includeSystemLabels: z\n .boolean()\n .optional()\n .default(true)\n .describe(\"Include system labels like INBOX, SENT\"),\n});\n\nexport type ListLabelsInput = z.infer<typeof ListLabelsSchema>;\n\nexport const GetOrCreateLabelSchema = z.object({\n name: z.string().min(1, \"Label name required\"),\n messageListVisibility: z.enum([\"show\", \"hide\"]).optional().default(\"show\"),\n labelListVisibility: z.enum([\"labelShow\", \"labelShowIfUnread\", \"labelHide\"]).optional(),\n backgroundColor: gmailLabelColorSchema.optional(),\n textColor: gmailLabelColorSchema.optional(),\n});\n\nexport type GetOrCreateLabelInput = z.infer<typeof GetOrCreateLabelSchema>;\n\n// Filter Management\n\n/**\n * Filter criteria for matching emails\n */\nexport const FilterCriteriaSchema = z.object({\n from: z.string().optional().describe(\"Match sender\"),\n to: z.string().optional().describe(\"Match recipient\"),\n subject: z.string().optional().describe(\"Match subject\"),\n query: z.string().optional().describe(\"Gmail search query\"),\n hasAttachment: z.boolean().optional().describe(\"Has attachment\"),\n excludeChats: z.boolean().optional().default(true).describe(\"Exclude chat messages\"),\n size: z.number().int().optional().describe(\"Size threshold in bytes\"),\n sizeComparison: z.enum([\"larger\", \"smaller\"]).optional().describe(\"Size comparison\"),\n});\n\nexport type FilterCriteriaInput = z.infer<typeof FilterCriteriaSchema>;\n\n/**\n * Actions to perform on matching emails\n */\nexport const FilterActionSchema = z.object({\n addLabelIds: z.array(z.string()).optional().describe(\"Label IDs to add\"),\n removeLabelIds: z.array(z.string()).optional().describe(\"Label IDs to remove\"),\n forward: z.string().email().optional().describe(\"Forward to email address\"),\n});\n\nexport type FilterActionInput = z.infer<typeof FilterActionSchema>;\n\n/**\n * Template types for common filter use cases\n */\nexport const FilterTemplateType = z.enum([\n \"fromSender\",\n \"withSubject\",\n \"withAttachments\",\n \"largeEmails\",\n \"mailingList\",\n]);\n\nexport type FilterTemplateTypeValue = z.infer<typeof FilterTemplateType>;\n\n/**\n * Create filter - supports direct criteria/action or pre-built templates\n */\nexport const CreateFilterSchema = z\n .object({\n // Direct mode\n criteria: FilterCriteriaSchema.optional(),\n action: FilterActionSchema.optional(),\n // Template mode\n template: FilterTemplateType.optional().describe(\"Use a pre-built template\"),\n labelIds: z.array(z.string()).optional().describe(\"Label IDs for template mode\"),\n archive: z.boolean().optional().default(false).describe(\"Remove from inbox (template mode)\"),\n email: z.string().email().optional().describe(\"Email address (for fromSender, mailingList)\"),\n subject: z.string().optional().describe(\"Subject text (for withSubject)\"),\n sizeBytes: z.number().int().optional().describe(\"Size in bytes (for largeEmails)\"),\n listAddress: z.string().optional().describe(\"Mailing list address (for mailingList)\"),\n })\n .refine(\n (data) => {\n // Either direct mode or template mode\n if (data.template) {\n // Template mode requires labelIds\n if (!data.labelIds || data.labelIds.length === 0) return false;\n // Template-specific validation\n switch (data.template) {\n case \"fromSender\":\n return !!data.email;\n case \"withSubject\":\n return !!data.subject;\n case \"largeEmails\":\n return !!data.sizeBytes;\n case \"mailingList\":\n return !!data.listAddress || !!data.email;\n case \"withAttachments\":\n return true;\n }\n } else {\n // Direct mode requires criteria and action\n return !!data.criteria && !!data.action;\n }\n },\n {\n message:\n \"Provide either (criteria + action) for direct mode, or (template + labelIds) for template mode\",\n },\n );\n\nexport type CreateFilterInput = z.infer<typeof CreateFilterSchema>;\n\nexport const ListFiltersSchema = z.object({\n filterId: z\n .string()\n .optional()\n .describe(\"Optional filter ID to get details of a specific filter\"),\n});\n\nexport type ListFiltersInput = z.infer<typeof ListFiltersSchema>;\n\nexport const DeleteFilterSchema = z.object({\n filterId: z.string().min(1, \"Filter ID required\"),\n});\n\nexport type DeleteFilterInput = z.infer<typeof DeleteFilterSchema>;\n", "import type { drive_v3 } from \"googleapis\";\nimport type { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { log } from \"../utils/index.js\";\nimport {\n GOOGLE_MIME_TYPES,\n TEXT_MIME_TYPES as MIME_TEXT_TYPES,\n getExtension,\n getMimeTypeFromExtension,\n} from \"../utils/mimeTypes.js\";\nimport { escapeQueryString, combineQueries } from \"../utils/gdrive-query.js\";\nimport {\n getCachedPath,\n setCachedPath,\n getCachedSegment,\n setCachedSegment,\n} from \"../utils/pathCache.js\";\n\n/**\n * Context passed to handlers for access to MCP features like progress and elicitation\n */\nexport interface HandlerContext {\n /** The MCP server instance */\n server: Server;\n /** Progress token from the client request (if provided) */\n progressToken?: string | number;\n}\n\n// Re-export FOLDER_MIME_TYPE for backward compatibility\nexport const FOLDER_MIME_TYPE = GOOGLE_MIME_TYPES.FOLDER;\n\n// Re-export TEXT_MIME_TYPES for backward compatibility\nexport const TEXT_MIME_TYPES: Record<string, string> = {\n txt: MIME_TEXT_TYPES.PLAIN,\n md: MIME_TEXT_TYPES.MARKDOWN,\n};\n\nexport function getExtensionFromFilename(filename: string): string {\n return getExtension(filename);\n}\n\nexport function getMimeTypeFromFilename(filename: string): string {\n return getMimeTypeFromExtension(filename);\n}\n\n/**\n * For text-based files, ensure they have a valid extension.\n */\nexport function validateTextFileExtension(name: string): void {\n const ext = getExtensionFromFilename(name);\n if (![\"txt\", \"md\"].includes(ext)) {\n throw new Error(\"File name must end with .txt or .md for text files.\");\n }\n}\n\ninterface ResolvePathOptions {\n /** Create intermediate folders if they don't exist (default: true) */\n createIfMissing?: boolean;\n}\n\n/**\n * Core path resolution function. Resolves a slash-delimited path to a folder ID.\n *\n * @param drive - Google Drive API instance\n * @param pathStr - Path to resolve (e.g., \"/some/folder\")\n * @param options - Resolution options\n * @returns The resolved folder ID\n */\nasync function resolvePathCore(\n drive: drive_v3.Drive,\n pathStr: string,\n options: ResolvePathOptions = {},\n): Promise<string> {\n const { createIfMissing = true } = options;\n\n if (!pathStr || pathStr === \"/\") return \"root\";\n\n // Check full path cache first\n const cachedPath = getCachedPath(pathStr);\n if (cachedPath) {\n log(\"Path cache hit\", { path: pathStr, fileId: cachedPath });\n return cachedPath;\n }\n\n const parts = pathStr.replace(/^\\/+|\\/+$/g, \"\").split(\"/\");\n let currentFolderId: string = \"root\";\n\n for (const part of parts) {\n if (!part) continue;\n\n // Check segment cache\n const cachedSegment = getCachedSegment(currentFolderId, part);\n if (cachedSegment) {\n currentFolderId = cachedSegment;\n continue;\n }\n\n const escapedPart = escapeQueryString(part);\n const response = await drive.files.list({\n q: combineQueries(\n `'${currentFolderId}' in parents`,\n `name = '${escapedPart}'`,\n `mimeType = '${FOLDER_MIME_TYPE}'`,\n \"trashed = false\",\n ),\n fields: \"files(id)\",\n spaces: \"drive\",\n includeItemsFromAllDrives: true,\n supportsAllDrives: true,\n });\n\n if (!response.data.files?.length) {\n if (!createIfMissing) {\n throw new Error(`Folder not found: ${part} in path ${pathStr}`);\n }\n\n // Create the missing folder\n const folder = await drive.files.create({\n requestBody: {\n name: part,\n mimeType: FOLDER_MIME_TYPE,\n parents: [currentFolderId],\n },\n fields: \"id\",\n supportsAllDrives: true,\n });\n\n if (!folder.data.id) {\n throw new Error(`Failed to create intermediate folder: ${part}`);\n }\n\n setCachedSegment(currentFolderId, part, folder.data.id);\n currentFolderId = folder.data.id;\n } else {\n const foundId = response.data.files[0].id!;\n setCachedSegment(currentFolderId, part, foundId);\n currentFolderId = foundId;\n }\n }\n\n setCachedPath(pathStr, currentFolderId);\n return currentFolderId;\n}\n\n/**\n * Resolve a slash-delimited path (e.g. \"/some/folder\") within Google Drive\n * into a folder ID. Creates folders if they don't exist.\n */\nexport async function resolvePath(drive: drive_v3.Drive, pathStr: string): Promise<string> {\n return resolvePathCore(drive, pathStr, { createIfMissing: true });\n}\n\n/**\n * Resolve a folder ID or path.\n * If it's a path (starts with '/'), resolve it.\n * If no folder is provided, return 'root'.\n */\nexport async function resolveFolderId(\n drive: drive_v3.Drive,\n input: string | undefined,\n): Promise<string> {\n if (!input) return \"root\";\n\n if (input.startsWith(\"/\")) {\n // Input is a path\n return resolvePath(drive, input);\n } else {\n // Input is a folder ID, return as-is\n return input;\n }\n}\n\n/**\n * Resolve optional folder parameters where user can provide either folderId OR folderPath.\n * Throws if both are provided. Returns 'root' if neither is provided.\n * Creates intermediate folders if folderPath doesn't exist.\n */\nexport async function resolveOptionalFolderPath(\n drive: drive_v3.Drive,\n folderId?: string,\n folderPath?: string,\n): Promise<string> {\n if (folderId && folderPath) {\n throw new Error(\"Provide either folderId or folderPath, not both\");\n }\n if (folderId) return folderId;\n if (folderPath) return resolvePath(drive, folderPath);\n return \"root\";\n}\n\n/**\n * Resolve a file by ID or path. Returns the file ID.\n * Unlike folder resolution, this does NOT create the file if it doesn't exist.\n */\nexport async function resolveFileIdFromPath(\n drive: drive_v3.Drive,\n fileId?: string,\n filePath?: string,\n): Promise<string> {\n if (fileId && filePath) {\n throw new Error(\"Provide either fileId or filePath, not both\");\n }\n if (!fileId && !filePath) {\n throw new Error(\"Either fileId or filePath must be provided\");\n }\n if (fileId) return fileId;\n\n // Parse path to get parent folder and filename\n const normalizedPath = filePath!.replace(/^\\/+|\\/+$/g, \"\");\n const parts = normalizedPath.split(\"/\");\n const fileName = parts.pop();\n\n if (!fileName) {\n throw new Error(\"Invalid file path: no filename specified\");\n }\n\n // Resolve parent folder (don't create if missing)\n let parentFolderId = \"root\";\n if (parts.length > 0) {\n const parentPath = \"/\" + parts.join(\"/\");\n parentFolderId = await resolvePathWithoutCreate(drive, parentPath);\n }\n\n // Find the file in the parent folder\n const escapedName = escapeQueryString(fileName);\n const response = await drive.files.list({\n q: combineQueries(\n `'${parentFolderId}' in parents`,\n `name = '${escapedName}'`,\n \"trashed = false\",\n ),\n fields: \"files(id, name)\",\n pageSize: 1,\n includeItemsFromAllDrives: true,\n supportsAllDrives: true,\n });\n\n if (!response.data.files?.length) {\n throw new Error(`File not found: ${filePath}`);\n }\n\n return response.data.files[0].id!;\n}\n\n/**\n * Resolve a path without creating folders. Throws if any folder doesn't exist.\n */\nasync function resolvePathWithoutCreate(drive: drive_v3.Drive, pathStr: string): Promise<string> {\n return resolvePathCore(drive, pathStr, { createIfMissing: false });\n}\n\n/**\n * Result of checking file existence. Discriminated union allows callers to\n * distinguish \"file not found\" from \"API error\".\n */\nexport type FileExistsResult =\n | { status: \"found\"; id: string }\n | { status: \"not_found\" }\n | { status: \"error\"; error: Error };\n\n/**\n * Check if a file with the given name already exists in the specified folder.\n * Returns a discriminated union allowing callers to distinguish between\n * \"file found\", \"file not found\", and \"API error\" cases.\n */\nexport async function checkFileExistsResult(\n drive: drive_v3.Drive,\n name: string,\n parentFolderId: string = \"root\",\n): Promise<FileExistsResult> {\n try {\n const escapedName = escapeQueryString(name);\n const query = combineQueries(\n `name = '${escapedName}'`,\n `'${parentFolderId}' in parents`,\n \"trashed = false\",\n );\n\n const res = await drive.files.list({\n q: query,\n fields: \"files(id, name, mimeType)\",\n pageSize: 1,\n includeItemsFromAllDrives: true,\n supportsAllDrives: true,\n });\n\n if (res.data.files && res.data.files.length > 0 && res.data.files[0].id) {\n return { status: \"found\", id: res.data.files[0].id };\n }\n return { status: \"not_found\" };\n } catch (error) {\n log(\"Error checking file existence:\", error);\n return { status: \"error\", error: error instanceof Error ? error : new Error(String(error)) };\n }\n}\n\n/**\n * Check if a file with the given name already exists in the specified folder.\n * Returns the file ID if it exists, null otherwise.\n *\n * @deprecated Use checkFileExistsResult() for better error handling.\n * This function cannot distinguish \"file not found\" from \"API error\".\n */\nexport async function checkFileExists(\n drive: drive_v3.Drive,\n name: string,\n parentFolderId: string = \"root\",\n): Promise<string | null> {\n const result = await checkFileExistsResult(drive, name, parentFolderId);\n if (result.status === \"found\") {\n return result.id;\n }\n return null;\n}\n\n/**\n * Convert A1 notation to GridRange for Google Sheets API\n */\nexport function convertA1ToGridRange(\n a1Notation: string,\n sheetId: number,\n): {\n sheetId: number;\n startColumnIndex?: number;\n endColumnIndex?: number;\n startRowIndex?: number;\n endRowIndex?: number;\n} {\n const rangeRegex = /^([A-Z]*)([0-9]*)(:([A-Z]*)([0-9]*))?$/;\n const match = a1Notation.match(rangeRegex);\n\n if (!match) {\n throw new Error(`Invalid A1 notation: ${a1Notation}`);\n }\n\n const [, startCol, startRow, , endCol, endRow] = match;\n\n const gridRange: {\n sheetId: number;\n startColumnIndex?: number;\n endColumnIndex?: number;\n startRowIndex?: number;\n endRowIndex?: number;\n } = { sheetId };\n\n // Convert column letters to numbers (A=0, B=1, etc.)\n const colToNum = (col: string): number => {\n let num = 0;\n for (let i = 0; i < col.length; i++) {\n num = num * 26 + (col.charCodeAt(i) - \"A\".charCodeAt(0) + 1);\n }\n return num - 1;\n };\n\n // Set start indices\n if (startCol) gridRange.startColumnIndex = colToNum(startCol);\n if (startRow) gridRange.startRowIndex = parseInt(startRow) - 1;\n\n // Set end indices (exclusive)\n if (endCol) {\n gridRange.endColumnIndex = colToNum(endCol) + 1;\n } else if (startCol && !endCol) {\n gridRange.endColumnIndex = gridRange.startColumnIndex! + 1;\n }\n\n if (endRow) {\n gridRange.endRowIndex = parseInt(endRow);\n } else if (startRow && !endRow) {\n gridRange.endRowIndex = gridRange.startRowIndex! + 1;\n }\n\n return gridRange;\n}\n\n// -----------------------------------------------------------------------------\n// EMU (English Metric Units) Conversion Helpers\n// -----------------------------------------------------------------------------\n// EMU is the native unit for Google Slides positioning. These constants and\n// functions help convert to/from common units.\n\nexport const EMU_PER_INCH = 914400;\nexport const EMU_PER_POINT = 12700;\nexport const EMU_PER_PIXEL_96DPI = 9525;\n\n// Standard Google Slides dimensions in EMU (default 16:9 aspect ratio)\nexport const SLIDES_WIDTH_EMU = 9144000; // 10 inches\nexport const SLIDES_HEIGHT_EMU = 5143500; // ~5.625 inches\n\nexport function inchesToEmu(inches: number): number {\n return Math.round(inches * EMU_PER_INCH);\n}\n\nexport function pointsToEmu(points: number): number {\n return Math.round(points * EMU_PER_POINT);\n}\n\nexport function pixelsToEmu(pixels: number, dpi = 96): number {\n return Math.round((pixels * EMU_PER_INCH) / dpi);\n}\n\nexport function emuToInches(emu: number): number {\n return emu / EMU_PER_INCH;\n}\n\nexport function emuToPoints(emu: number): number {\n return emu / EMU_PER_POINT;\n}\n\nexport function emuToPixels(emu: number, dpi = 96): number {\n return (emu * dpi) / EMU_PER_INCH;\n}\n\n// -----------------------------------------------------------------------------\n// Batch Operation Helpers\n// -----------------------------------------------------------------------------\n\nexport interface BatchResult<T> {\n success: T[];\n failed: Array<{ id: string; error: string }>;\n}\n\ninterface BatchOperationOptions {\n operationName: string;\n concurrency?: number;\n}\n\n/**\n * Generic batch operation processor that handles progress reporting vs rate-limited modes\n * and normalizes results into success/failed arrays.\n *\n * This abstracts the common pattern used by handleBatchDelete, handleBatchMove, handleBatchShare.\n */\nexport async function processBatchOperation<T>(\n ids: string[],\n operation: (id: string) => Promise<T>,\n context: HandlerContext | undefined,\n options: BatchOperationOptions,\n): Promise<BatchResult<T>> {\n // Dynamically import utils to avoid circular dependencies\n const { processBatchWithProgress, withRateLimitedBatch } = await import(\"../utils/index.js\");\n\n const concurrency = options.concurrency ?? 5;\n\n // Choose processing mode based on context availability\n const results = context?.server\n ? await processBatchWithProgress({\n server: context.server,\n progressToken: context.progressToken,\n items: ids,\n processor: operation,\n concurrency,\n operationName: options.operationName,\n })\n : await withRateLimitedBatch(ids, operation, {\n concurrency,\n operationName: options.operationName,\n });\n\n // Normalize results into success/failed arrays\n const success: T[] = [];\n const failed: Array<{ id: string; error: string }> = [];\n\n results.forEach((result, index) => {\n if (result.success) {\n success.push(result.result);\n } else {\n failed.push({\n id: ids[index],\n error: result.error,\n });\n }\n });\n\n return { success, failed };\n}\n", "/**\n * MIME type constants and mappings for Google Drive file types.\n * Consolidates duplicated MIME type definitions across handlers.\n */\n\n/** Google Workspace MIME types */\nexport const GOOGLE_MIME_TYPES = {\n DOCUMENT: \"application/vnd.google-apps.document\",\n SPREADSHEET: \"application/vnd.google-apps.spreadsheet\",\n PRESENTATION: \"application/vnd.google-apps.presentation\",\n FOLDER: \"application/vnd.google-apps.folder\",\n DRAWING: \"application/vnd.google-apps.drawing\",\n FORM: \"application/vnd.google-apps.form\",\n SCRIPT: \"application/vnd.google-apps.script\",\n SITE: \"application/vnd.google-apps.site\",\n SHORTCUT: \"application/vnd.google-apps.shortcut\",\n} as const;\n\n/** Text file MIME types */\nexport const TEXT_MIME_TYPES = {\n PLAIN: \"text/plain\",\n MARKDOWN: \"text/markdown\",\n CSV: \"text/csv\",\n HTML: \"text/html\",\n} as const;\n\n/** Export MIME types for downloading Google Workspace files */\nexport const EXPORT_MIME_TYPES = {\n PDF: \"application/pdf\",\n DOCX: \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n XLSX: \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n PPTX: \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\n RTF: \"application/rtf\",\n ODT: \"application/vnd.oasis.opendocument.text\",\n ODS: \"application/vnd.oasis.opendocument.spreadsheet\",\n ODP: \"application/vnd.oasis.opendocument.presentation\",\n ZIP: \"application/zip\",\n EPUB: \"application/epub+zip\",\n} as const;\n\n/** File type categories */\nexport type FileType = \"doc\" | \"sheet\" | \"slides\" | \"text\";\n\n/** Map file extensions to their type category */\nexport const EXTENSION_TO_TYPE: Record<string, FileType> = {\n // Google Doc types\n docx: \"doc\",\n doc: \"doc\",\n gdoc: \"doc\",\n odt: \"doc\",\n rtf: \"doc\",\n // Google Sheet types\n xlsx: \"sheet\",\n xls: \"sheet\",\n csv: \"sheet\",\n gsheet: \"sheet\",\n ods: \"sheet\",\n // Google Slides types\n pptx: \"slides\",\n ppt: \"slides\",\n gslides: \"slides\",\n odp: \"slides\",\n // Text types\n txt: \"text\",\n md: \"text\",\n};\n\n/** Map file extensions to their MIME type */\nexport const EXTENSION_TO_MIME: Record<string, string> = {\n txt: TEXT_MIME_TYPES.PLAIN,\n md: TEXT_MIME_TYPES.MARKDOWN,\n csv: TEXT_MIME_TYPES.CSV,\n html: TEXT_MIME_TYPES.HTML,\n};\n\n/**\n * Get the file extension from a filename.\n */\nexport function getExtension(filename: string): string {\n return filename.split(\".\").pop()?.toLowerCase() || \"\";\n}\n\n/**\n * Infer file type from filename extension.\n */\nexport function inferTypeFromExtension(filename: string): FileType | undefined {\n const ext = getExtension(filename);\n return EXTENSION_TO_TYPE[ext];\n}\n\n/**\n * Get MIME type from filename extension for text files.\n */\nexport function getMimeTypeFromExtension(filename: string): string {\n const ext = getExtension(filename);\n return EXTENSION_TO_MIME[ext] || TEXT_MIME_TYPES.PLAIN;\n}\n\n/**\n * Check if a MIME type is a Google Workspace type.\n */\nexport function isGoogleWorkspaceMimeType(mimeType: string): boolean {\n return mimeType.startsWith(\"application/vnd.google-apps.\");\n}\n\n/**\n * Check if a MIME type is a folder.\n */\nexport function isFolder(mimeType: string): boolean {\n return mimeType === GOOGLE_MIME_TYPES.FOLDER;\n}\n\n/**\n * Get the file type category from a Google Workspace MIME type.\n */\nexport function getTypeFromGoogleMime(mimeType: string): FileType | undefined {\n switch (mimeType) {\n case GOOGLE_MIME_TYPES.DOCUMENT:\n return \"doc\";\n case GOOGLE_MIME_TYPES.SPREADSHEET:\n return \"sheet\";\n case GOOGLE_MIME_TYPES.PRESENTATION:\n return \"slides\";\n default:\n return undefined;\n }\n}\n\n/**\n * Returns a suggestion for which tool to use based on the file's MIME type.\n * Used when a user calls the wrong specific handler (e.g., getGoogleDocContent on a Sheet).\n */\nexport function getMimeTypeSuggestion(mimeType: string | null | undefined): string {\n switch (mimeType) {\n case GOOGLE_MIME_TYPES.DOCUMENT:\n return \"Use getGoogleDocContent for Google Docs.\";\n case GOOGLE_MIME_TYPES.SPREADSHEET:\n return \"Use getGoogleSheetContent for spreadsheets.\";\n case GOOGLE_MIME_TYPES.PRESENTATION:\n return \"Use getGoogleSlidesContent for presentations.\";\n default:\n return \"Use getFileContent for automatic type detection.\";\n }\n}\n", "import type { drive_v3, docs_v1 } from \"googleapis\";\nimport {\n log,\n successResponse,\n structuredResponse,\n errorResponse,\n withTimeout,\n validateArgs,\n} from \"../utils/index.js\";\nimport { GOOGLE_MIME_TYPES, getMimeTypeSuggestion } from \"../utils/mimeTypes.js\";\nimport type { ToolResponse } from \"../utils/index.js\";\nimport {\n CreateGoogleDocSchema,\n UpdateGoogleDocSchema,\n GetGoogleDocContentSchema,\n AppendToDocSchema,\n InsertTextInDocSchema,\n DeleteTextInDocSchema,\n ReplaceTextInDocSchema,\n FormatGoogleDocRangeSchema,\n} from \"../schemas/index.js\";\nimport { resolveOptionalFolderPath, checkFileExists } from \"./helpers.js\";\nimport { toDocsColorStyle } from \"../utils/colors.js\";\n\n/**\n * Get the end index of a Google Doc's content.\n * Used for calculating document length and insert positions.\n */\nfunction getDocumentEndIndex(document: docs_v1.Schema$Document): number {\n const content = document.body?.content;\n if (!content || content.length === 0) return 1;\n return content[content.length - 1]?.endIndex || 1;\n}\n\nexport async function handleCreateGoogleDoc(\n drive: drive_v3.Drive,\n docs: docs_v1.Docs,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(CreateGoogleDocSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n const parentFolderId = await resolveOptionalFolderPath(\n drive,\n data.parentFolderId,\n data.parentPath,\n );\n\n // Check if document already exists\n const existingFileId = await checkFileExists(drive, data.name, parentFolderId);\n if (existingFileId) {\n return errorResponse(\n `A document named \"${data.name}\" already exists in this location. ` +\n `To update it, use updateGoogleDoc with documentId: ${existingFileId}`,\n { code: \"ALREADY_EXISTS\", context: { existingFileId } },\n );\n }\n\n log(\"Creating Google Doc\", { parentFolderId });\n\n // Create empty doc\n let docResponse;\n try {\n docResponse = await drive.files.create({\n requestBody: {\n name: data.name,\n mimeType: \"application/vnd.google-apps.document\",\n parents: [parentFolderId],\n },\n fields: \"id, name, webViewLink\",\n supportsAllDrives: true,\n });\n } catch (createError: unknown) {\n const err = createError as {\n message?: string;\n code?: number;\n errors?: unknown;\n status?: number;\n };\n log(\"Drive files.create error details:\", {\n message: err.message,\n code: err.code,\n errors: err.errors,\n status: err.status,\n });\n throw createError;\n }\n const doc = docResponse.data;\n\n await docs.documents.batchUpdate({\n documentId: doc.id!,\n requestBody: {\n requests: [\n {\n insertText: { location: { index: 1 }, text: data.content },\n },\n // Ensure the text is formatted as normal text, not as a header\n {\n updateParagraphStyle: {\n range: {\n startIndex: 1,\n endIndex: data.content.length + 1,\n },\n paragraphStyle: {\n namedStyleType: \"NORMAL_TEXT\",\n },\n fields: \"namedStyleType\",\n },\n },\n ],\n },\n });\n\n return successResponse(\n `Created Google Doc: ${doc.name}\\nID: ${doc.id}\\nLink: ${doc.webViewLink}`,\n );\n}\n\nexport async function handleUpdateGoogleDoc(\n docs: docs_v1.Docs,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(UpdateGoogleDocSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n const document = await docs.documents.get({ documentId: data.documentId });\n\n // Delete all content\n const endIndex = getDocumentEndIndex(document.data);\n\n // Google Docs API doesn't allow deleting the final newline character\n // We need to leave at least one character in the document\n const deleteEndIndex = Math.max(1, endIndex - 1);\n\n if (deleteEndIndex > 1) {\n await docs.documents.batchUpdate({\n documentId: data.documentId,\n requestBody: {\n requests: [\n {\n deleteContentRange: {\n range: { startIndex: 1, endIndex: deleteEndIndex },\n },\n },\n ],\n },\n });\n }\n\n // Insert new content\n await docs.documents.batchUpdate({\n documentId: data.documentId,\n requestBody: {\n requests: [\n {\n insertText: { location: { index: 1 }, text: data.content },\n },\n // Ensure the text is formatted as normal text, not as a header\n {\n updateParagraphStyle: {\n range: {\n startIndex: 1,\n endIndex: data.content.length + 1,\n },\n paragraphStyle: {\n namedStyleType: \"NORMAL_TEXT\",\n },\n fields: \"namedStyleType\",\n },\n },\n ],\n },\n });\n\n return successResponse(`Updated Google Doc: ${document.data.title}`);\n}\n\nexport async function handleGetGoogleDocContent(\n drive: drive_v3.Drive,\n docs: docs_v1.Docs,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(GetGoogleDocContentSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Check file type before calling Docs API to provide helpful error messages\n const metadata = await drive.files.get({\n fileId: data.documentId,\n fields: \"mimeType,name\",\n supportsAllDrives: true,\n });\n\n const mimeType = metadata.data.mimeType;\n if (mimeType !== GOOGLE_MIME_TYPES.DOCUMENT) {\n const fileName = metadata.data.name || data.documentId;\n const suggestion = getMimeTypeSuggestion(mimeType);\n return errorResponse(`\"${fileName}\" is not a Google Doc (type: ${mimeType}). ${suggestion}`);\n }\n\n const document = await withTimeout(\n docs.documents.get({ documentId: data.documentId }),\n 30000,\n \"Get document content\",\n );\n\n const contentSegments: Array<{\n startIndex: number;\n endIndex: number;\n text: string;\n }> = [];\n let content = \"\";\n let currentIndex = 1;\n\n // Extract text content with indices\n if (document.data.body?.content) {\n for (const element of document.data.body.content) {\n if (element.paragraph?.elements) {\n for (const textElement of element.paragraph.elements) {\n if (textElement.textRun?.content) {\n const text = textElement.textRun.content;\n const startIdx = currentIndex;\n content += text;\n currentIndex += text.length;\n contentSegments.push({\n startIndex: startIdx,\n endIndex: currentIndex,\n text: text,\n });\n }\n }\n }\n }\n }\n\n // Format the response to show text with indices\n let formattedContent = \"Document content with indices:\\n\\n\";\n let lineStart = 1;\n const lines = content.split(\"\\n\");\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const lineEnd = lineStart + line.length;\n if (line.trim()) {\n formattedContent += `[${lineStart}-${lineEnd}] ${line}\\n`;\n }\n lineStart = lineEnd + 1; // +1 for the newline character\n }\n\n const textResponse = formattedContent + `\\nTotal length: ${content.length} characters`;\n\n return structuredResponse(textResponse, {\n documentId: data.documentId,\n title: document.data.title,\n content: contentSegments,\n totalLength: content.length,\n });\n}\n\nexport async function handleAppendToDoc(docs: docs_v1.Docs, args: unknown): Promise<ToolResponse> {\n const validation = validateArgs(AppendToDocSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Get document to find end index\n const document = await docs.documents.get({ documentId: data.documentId });\n const endIndex = getDocumentEndIndex(document.data);\n\n // Insert at end index - 1 (before the final newline)\n const insertIndex = Math.max(1, endIndex - 1);\n\n // Prepare the text to insert\n const textToInsert = data.insertNewline ? `\\n${data.text}` : data.text;\n\n await docs.documents.batchUpdate({\n documentId: data.documentId,\n requestBody: {\n requests: [\n {\n insertText: {\n location: { index: insertIndex },\n text: textToInsert,\n },\n },\n ],\n },\n });\n\n log(\"Text appended to document\", {\n documentId: data.documentId,\n textLength: data.text.length,\n });\n\n return successResponse(\n `Appended ${data.text.length} characters to document \"${document.data.title}\"`,\n );\n}\n\nexport async function handleInsertTextInDoc(\n docs: docs_v1.Docs,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(InsertTextInDocSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Get document to validate index and get title\n const document = await docs.documents.get({ documentId: data.documentId });\n const docLength = getDocumentEndIndex(document.data);\n\n if (data.index >= docLength) {\n return errorResponse(\n `Index ${data.index} is beyond the document length (${docLength - 1} characters). ` +\n `Use appendToDoc to add text at the end, or specify an index between 1 and ${docLength - 1}.`,\n );\n }\n\n await docs.documents.batchUpdate({\n documentId: data.documentId,\n requestBody: {\n requests: [\n {\n insertText: {\n location: { index: data.index },\n text: data.text,\n },\n },\n ],\n },\n });\n\n log(\"Text inserted into document\", {\n documentId: data.documentId,\n index: data.index,\n textLength: data.text.length,\n });\n\n return successResponse(\n `Inserted ${data.text.length} characters at index ${data.index} in \"${document.data.title}\"`,\n );\n}\n\nexport async function handleDeleteTextInDoc(\n docs: docs_v1.Docs,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(DeleteTextInDocSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Get document to validate indices and get title\n const document = await docs.documents.get({ documentId: data.documentId });\n const docLength = getDocumentEndIndex(document.data);\n\n if (data.endIndex > docLength) {\n return errorResponse(\n `End index ${data.endIndex} is beyond the document length (${docLength - 1} characters). ` +\n `Valid range is 1 to ${docLength - 1}.`,\n );\n }\n\n const charsToDelete = data.endIndex - data.startIndex;\n\n await docs.documents.batchUpdate({\n documentId: data.documentId,\n requestBody: {\n requests: [\n {\n deleteContentRange: {\n range: {\n startIndex: data.startIndex,\n endIndex: data.endIndex,\n },\n },\n },\n ],\n },\n });\n\n log(\"Text deleted from document\", {\n documentId: data.documentId,\n startIndex: data.startIndex,\n endIndex: data.endIndex,\n });\n\n return successResponse(\n `Deleted ${charsToDelete} characters (indices ${data.startIndex}-${data.endIndex}) from \"${document.data.title}\"`,\n );\n}\n\nexport async function handleReplaceTextInDoc(\n docs: docs_v1.Docs,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(ReplaceTextInDocSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Get document title\n const document = await docs.documents.get({ documentId: data.documentId });\n\n const response = await docs.documents.batchUpdate({\n documentId: data.documentId,\n requestBody: {\n requests: [\n {\n replaceAllText: {\n containsText: {\n text: data.searchText,\n matchCase: data.matchCase,\n },\n replaceText: data.replaceText,\n },\n },\n ],\n },\n });\n\n // Get the number of replacements made\n const occurrencesChanged = response.data.replies?.[0]?.replaceAllText?.occurrencesChanged || 0;\n\n log(\"Text replaced in document\", {\n documentId: data.documentId,\n occurrences: occurrencesChanged,\n });\n\n if (occurrencesChanged === 0) {\n return successResponse(\n `No occurrences of \"${data.searchText}\" found in \"${document.data.title}\"`,\n );\n }\n\n return successResponse(\n `Replaced ${occurrencesChanged} occurrence(s) of \"${data.searchText}\" with \"${data.replaceText}\" in \"${document.data.title}\"`,\n );\n}\n\n// -----------------------------------------------------------------------------\n// DOC FORMATTING HELPERS\n// -----------------------------------------------------------------------------\n\ninterface DocTextFormatOptions {\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n strikethrough?: boolean;\n fontSize?: number;\n fontFamily?: string;\n foregroundColor?: { red?: number; green?: number; blue?: number };\n}\n\nfunction buildDocTextStyle(data: DocTextFormatOptions): {\n style: Record<string, unknown>;\n fields: string[];\n} {\n const style: Record<string, unknown> = {};\n const fields: string[] = [];\n\n if (data.bold !== undefined) {\n style.bold = data.bold;\n fields.push(\"bold\");\n }\n if (data.italic !== undefined) {\n style.italic = data.italic;\n fields.push(\"italic\");\n }\n if (data.underline !== undefined) {\n style.underline = data.underline;\n fields.push(\"underline\");\n }\n if (data.strikethrough !== undefined) {\n style.strikethrough = data.strikethrough;\n fields.push(\"strikethrough\");\n }\n if (data.fontSize !== undefined) {\n style.fontSize = { magnitude: data.fontSize, unit: \"PT\" };\n fields.push(\"fontSize\");\n }\n if (data.fontFamily !== undefined) {\n style.weightedFontFamily = { fontFamily: data.fontFamily };\n fields.push(\"weightedFontFamily\");\n }\n if (data.foregroundColor) {\n style.foregroundColor = toDocsColorStyle(data.foregroundColor);\n fields.push(\"foregroundColor\");\n }\n\n return { style, fields };\n}\n\ninterface DocParagraphFormatOptions {\n namedStyleType?: string;\n alignment?: string;\n lineSpacing?: number;\n spaceAbove?: number;\n spaceBelow?: number;\n}\n\nfunction buildDocParagraphStyle(data: DocParagraphFormatOptions): {\n style: Record<string, unknown>;\n fields: string[];\n} {\n const style: Record<string, unknown> = {};\n const fields: string[] = [];\n\n if (data.namedStyleType !== undefined) {\n style.namedStyleType = data.namedStyleType;\n fields.push(\"namedStyleType\");\n }\n if (data.alignment !== undefined) {\n style.alignment = data.alignment;\n fields.push(\"alignment\");\n }\n if (data.lineSpacing !== undefined) {\n style.lineSpacing = data.lineSpacing;\n fields.push(\"lineSpacing\");\n }\n if (data.spaceAbove !== undefined) {\n style.spaceAbove = { magnitude: data.spaceAbove, unit: \"PT\" };\n fields.push(\"spaceAbove\");\n }\n if (data.spaceBelow !== undefined) {\n style.spaceBelow = { magnitude: data.spaceBelow, unit: \"PT\" };\n fields.push(\"spaceBelow\");\n }\n\n return { style, fields };\n}\n\n// -----------------------------------------------------------------------------\n// DOC FORMATTING HANDLER\n// -----------------------------------------------------------------------------\n\nexport async function handleFormatGoogleDocRange(\n docs: docs_v1.Docs,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(FormatGoogleDocRangeSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n const document = await docs.documents.get({ documentId: data.documentId });\n const docEndIndex = getDocumentEndIndex(document.data);\n const startIndex = data.startIndex ?? 1;\n const endIndex = data.endIndex ?? docEndIndex;\n\n const requests: docs_v1.Schema$Request[] = [];\n const formatsApplied: string[] = [];\n\n const textResult = buildDocTextStyle(data);\n if (textResult.fields.length > 0) {\n requests.push({\n updateTextStyle: {\n range: { startIndex, endIndex },\n textStyle: textResult.style,\n fields: textResult.fields.join(\",\"),\n },\n });\n formatsApplied.push(...textResult.fields);\n }\n\n const paragraphResult = buildDocParagraphStyle(data);\n if (paragraphResult.fields.length > 0) {\n requests.push({\n updateParagraphStyle: {\n range: { startIndex, endIndex },\n paragraphStyle: paragraphResult.style,\n fields: paragraphResult.fields.join(\",\"),\n },\n });\n formatsApplied.push(...paragraphResult.fields);\n }\n\n if (requests.length === 0) {\n return errorResponse(\n \"No formatting options specified. Provide at least one of: \" +\n \"bold, italic, underline, strikethrough, fontSize, fontFamily, foregroundColor, \" +\n \"namedStyleType, alignment, lineSpacing, spaceAbove, spaceBelow.\",\n );\n }\n\n await docs.documents.batchUpdate({\n documentId: data.documentId,\n requestBody: { requests },\n });\n\n log(\"Applied formatting to document range\", {\n documentId: data.documentId,\n startIndex,\n endIndex,\n formatsApplied,\n });\n return successResponse(\n `Applied formatting to range ${startIndex}-${endIndex}: ${formatsApplied.join(\", \")}`,\n );\n}\n", "/**\n * Color conversion utilities for Google Workspace APIs.\n *\n * Each Google API (Docs, Sheets, Slides) uses slightly different\n * color structures. These helpers provide consistent conversions.\n */\n\n/**\n * RGB color with values between 0 and 1.\n */\nexport interface RgbColor {\n red?: number;\n green?: number;\n blue?: number;\n}\n\n/**\n * RGB color with optional alpha channel for transparency.\n */\nexport interface RgbColorWithAlpha extends RgbColor {\n alpha?: number;\n}\n\n/**\n * Normalize RGB color values, defaulting undefined values to 0.\n */\nexport function toRgbColor(color: RgbColor): {\n red: number;\n green: number;\n blue: number;\n} {\n return {\n red: color.red || 0,\n green: color.green || 0,\n blue: color.blue || 0,\n };\n}\n\n/**\n * Convert to Google Docs color style format.\n * Docs wraps RGB in { color: { rgbColor: {...} } }\n */\nexport function toDocsColorStyle(color: RgbColor): {\n color: { rgbColor: { red: number; green: number; blue: number } };\n} {\n return {\n color: {\n rgbColor: toRgbColor(color),\n },\n };\n}\n\n/**\n * Convert to Google Sheets color style format.\n * Sheets uses { rgbColor: {...} } directly.\n */\nexport function toSheetsColorStyle(color: RgbColor): {\n rgbColor: { red: number; green: number; blue: number };\n} {\n return {\n rgbColor: toRgbColor(color),\n };\n}\n\n/**\n * Convert to Google Slides color style format.\n * Slides uses { rgbColor: {...} } directly (same as Sheets).\n */\nexport function toSlidesColorStyle(color: RgbColor): {\n rgbColor: { red: number; green: number; blue: number };\n} {\n return {\n rgbColor: toRgbColor(color),\n };\n}\n\n/**\n * Convert to Google Slides solid fill format.\n * Used for shape and text box backgrounds.\n */\nexport function toSlidesSolidFill(color: RgbColorWithAlpha): {\n solidFill: {\n color: { rgbColor: { red: number; green: number; blue: number } };\n alpha: number;\n };\n} {\n return {\n solidFill: {\n color: toSlidesColorStyle(color),\n alpha: color.alpha ?? 1,\n },\n };\n}\n", "import type { drive_v3, sheets_v4 } from \"googleapis\";\nimport {\n successResponse,\n structuredResponse,\n errorResponse,\n withTimeout,\n validateArgs,\n} from \"../utils/index.js\";\nimport { GOOGLE_MIME_TYPES, getMimeTypeSuggestion } from \"../utils/mimeTypes.js\";\nimport type { ToolResponse } from \"../utils/index.js\";\nimport {\n SheetTabsSchema,\n CreateGoogleSheetSchema,\n UpdateGoogleSheetSchema,\n GetGoogleSheetContentSchema,\n FormatGoogleSheetCellsSchema,\n MergeGoogleSheetCellsSchema,\n AddGoogleSheetConditionalFormatSchema,\n} from \"../schemas/index.js\";\nimport { resolveOptionalFolderPath, checkFileExists, convertA1ToGridRange } from \"./helpers.js\";\nimport {\n getCachedSheetMetadata,\n setCachedSheetMetadata,\n clearSheetCache,\n} from \"../utils/sheetCache.js\";\nimport { toSheetsColorStyle } from \"../utils/colors.js\";\n\nasync function getSheetInfo(\n sheets: sheets_v4.Sheets,\n spreadsheetId: string,\n range: string,\n): Promise<{ sheetId: number; a1Range: string }> {\n const sheetName = range.includes(\"!\") ? range.split(\"!\")[0] : \"Sheet1\";\n const a1Range = range.includes(\"!\") ? range.split(\"!\")[1] : range;\n\n // Check cache first\n const cached = getCachedSheetMetadata(spreadsheetId, sheetName);\n if (cached) {\n return { sheetId: cached.sheetId, a1Range };\n }\n\n // Cache miss - fetch from API\n const rangeData = await sheets.spreadsheets.get({\n spreadsheetId,\n fields: \"sheets(properties(sheetId,title))\",\n });\n\n // Cache all sheets from this spreadsheet\n const sheetsData =\n rangeData.data.sheets\n ?.filter((s) => s.properties?.title && s.properties?.sheetId !== undefined)\n .map((s) => ({\n title: s.properties!.title!,\n sheetId: s.properties!.sheetId!,\n })) || [];\n\n if (sheetsData.length > 0) {\n setCachedSheetMetadata(spreadsheetId, sheetsData);\n }\n\n const sheet = sheetsData.find((s) => s.title === sheetName);\n if (!sheet) {\n const availableSheets = sheetsData.map((s) => s.title).join(\", \");\n throw new Error(\n `Sheet \"${sheetName}\" not found. Available sheets: ${availableSheets || \"none\"}`,\n );\n }\n\n return { sheetId: sheet.sheetId, a1Range };\n}\n\nexport async function handleCreateGoogleSheet(\n drive: drive_v3.Drive,\n sheets: sheets_v4.Sheets,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(CreateGoogleSheetSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n const parentFolderId = await resolveOptionalFolderPath(\n drive,\n data.parentFolderId,\n data.parentPath,\n );\n\n // Check if spreadsheet already exists\n const existingFileId = await checkFileExists(drive, data.name, parentFolderId);\n if (existingFileId) {\n return errorResponse(\n `A spreadsheet named \"${data.name}\" already exists in this location. ` +\n `To update it, use updateGoogleSheet with spreadsheetId: ${existingFileId}`,\n );\n }\n\n // Create spreadsheet with initial sheet\n const spreadsheet = await sheets.spreadsheets.create({\n requestBody: {\n properties: { title: data.name },\n sheets: [\n {\n properties: {\n sheetId: 0,\n title: \"Sheet1\",\n gridProperties: {\n rowCount: Math.max(data.data.length, 1000),\n columnCount: Math.max(data.data[0]?.length || 0, 26),\n },\n },\n },\n ],\n },\n });\n\n await drive.files.update({\n fileId: spreadsheet.data.spreadsheetId || \"\",\n addParents: parentFolderId,\n removeParents: \"root\",\n fields: \"id, name, webViewLink\",\n supportsAllDrives: true,\n });\n\n // Now update with data\n await sheets.spreadsheets.values.update({\n spreadsheetId: spreadsheet.data.spreadsheetId!,\n range: \"Sheet1!A1\",\n valueInputOption: data.valueInputOption || \"RAW\",\n requestBody: { values: data.data },\n });\n\n return successResponse(\n `Created Google Sheet: ${data.name}\\nID: ${spreadsheet.data.spreadsheetId}`,\n );\n}\n\nexport async function handleUpdateGoogleSheet(\n sheets: sheets_v4.Sheets,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(UpdateGoogleSheetSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n await sheets.spreadsheets.values.update({\n spreadsheetId: data.spreadsheetId,\n range: data.range,\n valueInputOption: data.valueInputOption || \"RAW\",\n requestBody: { values: data.data },\n });\n\n return successResponse(`Updated Google Sheet range: ${data.range}`);\n}\n\nexport async function handleGetGoogleSheetContent(\n drive: drive_v3.Drive,\n sheets: sheets_v4.Sheets,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(GetGoogleSheetContentSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Check file type before calling Sheets API to provide helpful error messages\n const metadata = await drive.files.get({\n fileId: data.spreadsheetId,\n fields: \"mimeType,name\",\n supportsAllDrives: true,\n });\n\n const mimeType = metadata.data.mimeType;\n if (mimeType !== GOOGLE_MIME_TYPES.SPREADSHEET) {\n const fileName = metadata.data.name || data.spreadsheetId;\n const suggestion = getMimeTypeSuggestion(mimeType);\n return errorResponse(`\"${fileName}\" is not a Google Sheet (type: ${mimeType}). ${suggestion}`);\n }\n\n // If no range specified, get the first sheet name and use it as range\n let range = data.range;\n if (!range) {\n const spreadsheet = await sheets.spreadsheets.get({\n spreadsheetId: data.spreadsheetId,\n fields: \"sheets(properties(title))\",\n });\n\n const firstSheetName = spreadsheet.data.sheets?.[0]?.properties?.title || \"Sheet1\";\n range = firstSheetName;\n }\n\n const response = await withTimeout(\n sheets.spreadsheets.values.get({\n spreadsheetId: data.spreadsheetId,\n range: range,\n }),\n 30000,\n \"Get sheet content\",\n );\n\n const values = response.data.values || [];\n let content = `Content for range ${range}:\\n\\n`;\n\n if (values.length === 0) {\n content += \"(empty range)\";\n } else {\n values.forEach((row, rowIndex) => {\n content += `Row ${rowIndex + 1}: ${row.join(\", \")}\\n`;\n });\n }\n\n const rowCount = values.length;\n const columnCount = values.length > 0 ? Math.max(...values.map((row) => row.length)) : 0;\n\n return structuredResponse(content, {\n spreadsheetId: data.spreadsheetId,\n range: range,\n values: values,\n rowCount: rowCount,\n columnCount: columnCount,\n });\n}\n\n// -----------------------------------------------------------------------------\n// SHEET FORMATTING HELPERS\n// -----------------------------------------------------------------------------\n\ninterface SheetFormatOptions {\n backgroundColor?: { red?: number; green?: number; blue?: number };\n horizontalAlignment?: string;\n verticalAlignment?: string;\n wrapStrategy?: string;\n bold?: boolean;\n italic?: boolean;\n strikethrough?: boolean;\n underline?: boolean;\n fontSize?: number;\n fontFamily?: string;\n foregroundColor?: { red?: number; green?: number; blue?: number };\n numberFormat?: { pattern: string; type?: string };\n}\n\ninterface CellFormatResult {\n format: sheets_v4.Schema$CellFormat;\n fields: string[];\n appliedTypes: string[];\n}\n\nfunction buildCellFormat(data: SheetFormatOptions): CellFormatResult {\n const fields: string[] = [];\n const format: sheets_v4.Schema$CellFormat = {};\n const appliedTypes: string[] = [];\n\n if (data.backgroundColor) {\n format.backgroundColorStyle = toSheetsColorStyle(data.backgroundColor);\n fields.push(\"userEnteredFormat.backgroundColorStyle\");\n }\n if (data.horizontalAlignment) {\n format.horizontalAlignment = data.horizontalAlignment;\n fields.push(\"userEnteredFormat.horizontalAlignment\");\n }\n if (data.verticalAlignment) {\n format.verticalAlignment = data.verticalAlignment;\n fields.push(\"userEnteredFormat.verticalAlignment\");\n }\n if (data.wrapStrategy) {\n format.wrapStrategy = data.wrapStrategy;\n fields.push(\"userEnteredFormat.wrapStrategy\");\n }\n\n const textResult = buildTextFormat(data);\n if (textResult.fields.length > 0) {\n format.textFormat = textResult.format;\n fields.push(\"userEnteredFormat.textFormat(\" + textResult.fields.join(\",\") + \")\");\n appliedTypes.push(\"text\");\n }\n\n if (data.numberFormat) {\n format.numberFormat = {\n pattern: data.numberFormat.pattern,\n ...(data.numberFormat.type && { type: data.numberFormat.type }),\n };\n fields.push(\"userEnteredFormat.numberFormat\");\n appliedTypes.push(\"number\");\n }\n\n return { format, fields, appliedTypes };\n}\n\nfunction buildTextFormat(data: SheetFormatOptions): {\n format: sheets_v4.Schema$TextFormat;\n fields: string[];\n} {\n const fields: string[] = [];\n const format: sheets_v4.Schema$TextFormat = {};\n\n if (data.bold !== undefined) {\n format.bold = data.bold;\n fields.push(\"bold\");\n }\n if (data.italic !== undefined) {\n format.italic = data.italic;\n fields.push(\"italic\");\n }\n if (data.strikethrough !== undefined) {\n format.strikethrough = data.strikethrough;\n fields.push(\"strikethrough\");\n }\n if (data.underline !== undefined) {\n format.underline = data.underline;\n fields.push(\"underline\");\n }\n if (data.fontSize !== undefined) {\n format.fontSize = data.fontSize;\n fields.push(\"fontSize\");\n }\n if (data.fontFamily !== undefined) {\n format.fontFamily = data.fontFamily;\n fields.push(\"fontFamily\");\n }\n if (data.foregroundColor) {\n format.foregroundColorStyle = toSheetsColorStyle(data.foregroundColor);\n fields.push(\"foregroundColorStyle\");\n }\n\n return { format, fields };\n}\n\ninterface BorderOptions {\n style: string;\n width?: number;\n color?: { red?: number; green?: number; blue?: number };\n top?: boolean;\n bottom?: boolean;\n left?: boolean;\n right?: boolean;\n innerHorizontal?: boolean;\n innerVertical?: boolean;\n}\n\nfunction buildBordersRequest(\n gridRange: sheets_v4.Schema$GridRange,\n options: BorderOptions,\n): sheets_v4.Schema$UpdateBordersRequest {\n const border: sheets_v4.Schema$Border = {\n style: options.style,\n width: options.width || 1,\n ...(options.color && { colorStyle: toSheetsColorStyle(options.color) }),\n };\n\n const request: sheets_v4.Schema$UpdateBordersRequest = { range: gridRange };\n if (options.top !== false) request.top = border;\n if (options.bottom !== false) request.bottom = border;\n if (options.left !== false) request.left = border;\n if (options.right !== false) request.right = border;\n if (options.innerHorizontal) request.innerHorizontal = border;\n if (options.innerVertical) request.innerVertical = border;\n\n return request;\n}\n\n// -----------------------------------------------------------------------------\n// SHEET FORMATTING HANDLER\n// -----------------------------------------------------------------------------\n\nexport async function handleFormatGoogleSheetCells(\n sheets: sheets_v4.Sheets,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(FormatGoogleSheetCellsSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n let sheetInfo;\n try {\n sheetInfo = await getSheetInfo(sheets, data.spreadsheetId, data.range);\n } catch (err) {\n return errorResponse(err instanceof Error ? err.message : String(err));\n }\n\n const gridRange = convertA1ToGridRange(sheetInfo.a1Range, sheetInfo.sheetId);\n const requests: sheets_v4.Schema$Request[] = [];\n const appliedFormats: string[] = [];\n\n const cellResult = buildCellFormat(data);\n if (cellResult.fields.length > 0) {\n requests.push({\n repeatCell: {\n range: gridRange,\n cell: { userEnteredFormat: cellResult.format },\n fields: cellResult.fields.join(\",\"),\n },\n });\n appliedFormats.push(...cellResult.appliedTypes);\n if (appliedFormats.length === 0) appliedFormats.push(\"cell\");\n }\n\n if (data.borders) {\n requests.push({ updateBorders: buildBordersRequest(gridRange, data.borders) });\n appliedFormats.push(\"borders\");\n }\n\n if (requests.length === 0) {\n return errorResponse(\"No formatting options specified\");\n }\n\n await sheets.spreadsheets.batchUpdate({\n spreadsheetId: data.spreadsheetId,\n requestBody: { requests },\n });\n\n return successResponse(`Formatted cells in range ${data.range} (${appliedFormats.join(\", \")})`);\n}\n\nexport async function handleMergeGoogleSheetCells(\n sheets: sheets_v4.Sheets,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(MergeGoogleSheetCellsSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n let sheetInfo;\n try {\n sheetInfo = await getSheetInfo(sheets, data.spreadsheetId, data.range);\n } catch (err) {\n return errorResponse(err instanceof Error ? err.message : String(err));\n }\n\n const gridRange = convertA1ToGridRange(sheetInfo.a1Range, sheetInfo.sheetId);\n\n const requests: sheets_v4.Schema$Request[] = [\n {\n mergeCells: {\n range: gridRange,\n mergeType: data.mergeType,\n },\n },\n ];\n\n await sheets.spreadsheets.batchUpdate({\n spreadsheetId: data.spreadsheetId,\n requestBody: { requests },\n });\n\n return successResponse(`Merged cells in range ${data.range} with type ${data.mergeType}`);\n}\n\nexport async function handleAddGoogleSheetConditionalFormat(\n sheets: sheets_v4.Sheets,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(AddGoogleSheetConditionalFormatSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n let sheetInfo;\n try {\n sheetInfo = await getSheetInfo(sheets, data.spreadsheetId, data.range);\n } catch (err) {\n return errorResponse(err instanceof Error ? err.message : String(err));\n }\n\n const gridRange = convertA1ToGridRange(sheetInfo.a1Range, sheetInfo.sheetId);\n\n // Build condition based on type\n const booleanCondition: sheets_v4.Schema$BooleanCondition = {\n type: data.condition.type,\n values: [{ userEnteredValue: data.condition.value }],\n };\n\n const format: sheets_v4.Schema$CellFormat = {};\n if (data.format.backgroundColor) {\n format.backgroundColorStyle = toSheetsColorStyle(data.format.backgroundColor);\n }\n if (data.format.textFormat) {\n format.textFormat = {};\n if (data.format.textFormat.bold !== undefined) {\n format.textFormat.bold = data.format.textFormat.bold;\n }\n if (data.format.textFormat.foregroundColor) {\n format.textFormat.foregroundColorStyle = toSheetsColorStyle(\n data.format.textFormat.foregroundColor,\n );\n }\n }\n\n const requests: sheets_v4.Schema$Request[] = [\n {\n addConditionalFormatRule: {\n rule: {\n ranges: [gridRange],\n booleanRule: {\n condition: booleanCondition,\n format: format,\n },\n },\n index: 0,\n },\n },\n ];\n\n await sheets.spreadsheets.batchUpdate({\n spreadsheetId: data.spreadsheetId,\n requestBody: { requests },\n });\n\n return successResponse(`Added conditional formatting to range ${data.range}`);\n}\n\n/**\n * Helper function to resolve a sheet title to its sheetId.\n * Returns the sheetId if found, null otherwise.\n */\nasync function getSheetIdByTitle(\n sheets: sheets_v4.Sheets,\n spreadsheetId: string,\n title: string,\n): Promise<number | null> {\n // Check cache first\n const cached = getCachedSheetMetadata(spreadsheetId, title);\n if (cached) {\n return cached.sheetId;\n }\n\n // Fetch from API\n const response = await sheets.spreadsheets.get({\n spreadsheetId,\n fields: \"sheets(properties(sheetId,title))\",\n });\n\n const sheetsData =\n response.data.sheets\n ?.filter((s) => s.properties?.title && s.properties?.sheetId !== undefined)\n .map((s) => ({\n title: s.properties!.title!,\n sheetId: s.properties!.sheetId!,\n })) || [];\n\n // Cache all sheets\n if (sheetsData.length > 0) {\n setCachedSheetMetadata(spreadsheetId, sheetsData);\n }\n\n const sheet = sheetsData.find((s) => s.title === title);\n return sheet ? sheet.sheetId : null;\n}\n\n/**\n * Unified sheet tabs handler - list, create, delete, or rename tabs\n */\nexport async function handleSheetTabs(\n sheets: sheets_v4.Sheets,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(SheetTabsSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n switch (data.action) {\n case \"list\":\n return listSheetTabs(sheets, data.spreadsheetId);\n\n case \"create\":\n return createSheetTab(sheets, data.spreadsheetId, data.title!, data.index);\n\n case \"delete\":\n return deleteSheetTab(sheets, data.spreadsheetId, data.title!);\n\n case \"rename\":\n return renameSheetTab(sheets, data.spreadsheetId, data.currentTitle!, data.newTitle!);\n\n default:\n return errorResponse(`Unknown action: ${data.action}`);\n }\n}\n\nasync function listSheetTabs(\n sheets: sheets_v4.Sheets,\n spreadsheetId: string,\n): Promise<ToolResponse> {\n const response = await sheets.spreadsheets.get({\n spreadsheetId,\n fields:\n \"spreadsheetId,sheets(properties(sheetId,title,index,gridProperties(rowCount,columnCount)))\",\n });\n\n const tabs =\n response.data.sheets?.map((sheet) => ({\n sheetId: sheet.properties?.sheetId,\n title: sheet.properties?.title,\n index: sheet.properties?.index,\n rowCount: sheet.properties?.gridProperties?.rowCount,\n columnCount: sheet.properties?.gridProperties?.columnCount,\n })) || [];\n\n const tabList = tabs\n .map((t) => `${t.index}: ${t.title} (${t.rowCount}x${t.columnCount})`)\n .join(\"\\n\");\n\n return structuredResponse(`Spreadsheet has ${tabs.length} tab(s):\\n${tabList}`, {\n spreadsheetId,\n tabs,\n });\n}\n\nasync function createSheetTab(\n sheets: sheets_v4.Sheets,\n spreadsheetId: string,\n title: string,\n index?: number,\n): Promise<ToolResponse> {\n // Check if sheet name already exists\n const existingSheetId = await getSheetIdByTitle(sheets, spreadsheetId, title);\n if (existingSheetId !== null) {\n return errorResponse(`A sheet tab named \"${title}\" already exists in this spreadsheet.`, {\n code: \"ALREADY_EXISTS\",\n });\n }\n\n const addSheetRequest: sheets_v4.Schema$Request = {\n addSheet: {\n properties: {\n title,\n ...(index !== undefined && { index }),\n },\n },\n };\n\n const response = await sheets.spreadsheets.batchUpdate({\n spreadsheetId,\n requestBody: { requests: [addSheetRequest] },\n });\n\n clearSheetCache(spreadsheetId);\n const newSheetId = response.data.replies?.[0]?.addSheet?.properties?.sheetId;\n return successResponse(`Created new sheet tab \"${title}\" (ID: ${newSheetId})`);\n}\n\nasync function deleteSheetTab(\n sheets: sheets_v4.Sheets,\n spreadsheetId: string,\n title: string,\n): Promise<ToolResponse> {\n const sheetId = await getSheetIdByTitle(sheets, spreadsheetId, title);\n if (sheetId === null) {\n const spreadsheet = await sheets.spreadsheets.get({ spreadsheetId });\n const availableSheets =\n spreadsheet.data.sheets\n ?.map((s) => s.properties?.title)\n .filter(Boolean)\n .join(\", \") || \"none\";\n return errorResponse(`Sheet tab \"${title}\" not found. Available sheets: ${availableSheets}`);\n }\n\n try {\n await sheets.spreadsheets.batchUpdate({\n spreadsheetId,\n requestBody: { requests: [{ deleteSheet: { sheetId } }] },\n });\n } catch (error: unknown) {\n const err = error as { message?: string };\n if (err.message?.includes(\"last sheet\") || err.message?.includes(\"at least one sheet\")) {\n return errorResponse(`Cannot delete \"${title}\" - spreadsheet must have at least one sheet.`);\n }\n throw error;\n }\n\n clearSheetCache(spreadsheetId);\n return successResponse(`Deleted sheet tab \"${title}\"`);\n}\n\nasync function renameSheetTab(\n sheets: sheets_v4.Sheets,\n spreadsheetId: string,\n currentTitle: string,\n newTitle: string,\n): Promise<ToolResponse> {\n const sheetId = await getSheetIdByTitle(sheets, spreadsheetId, currentTitle);\n if (sheetId === null) {\n const spreadsheet = await sheets.spreadsheets.get({ spreadsheetId });\n const availableSheets =\n spreadsheet.data.sheets\n ?.map((s) => s.properties?.title)\n .filter(Boolean)\n .join(\", \") || \"none\";\n return errorResponse(\n `Sheet tab \"${currentTitle}\" not found. Available sheets: ${availableSheets}`,\n );\n }\n\n const existingNewId = await getSheetIdByTitle(sheets, spreadsheetId, newTitle);\n if (existingNewId !== null) {\n return errorResponse(`A sheet tab named \"${newTitle}\" already exists in this spreadsheet.`);\n }\n\n await sheets.spreadsheets.batchUpdate({\n spreadsheetId,\n requestBody: {\n requests: [\n {\n updateSheetProperties: {\n properties: { sheetId, title: newTitle },\n fields: \"title\",\n },\n },\n ],\n },\n });\n\n clearSheetCache(spreadsheetId);\n return successResponse(`Renamed sheet tab \"${currentTitle}\" to \"${newTitle}\"`);\n}\n", "/**\n * Simple in-memory cache for sheet metadata (sheetName \u2192 sheetId mapping).\n * Avoids redundant API calls when applying multiple formatting operations\n * to the same spreadsheet.\n */\n\ninterface SheetMetadata {\n sheetId: number;\n title: string;\n}\n\ninterface CacheEntry {\n sheets: Map<string, SheetMetadata>;\n timestamp: number;\n}\n\nconst TTL_MS = 60_000; // 60-second cache TTL\nconst cache = new Map<string, CacheEntry>();\n\nexport function getCachedSheetMetadata(\n spreadsheetId: string,\n sheetName: string,\n): SheetMetadata | undefined {\n const entry = cache.get(spreadsheetId);\n if (!entry) return undefined;\n\n // Check if cache is expired\n if (Date.now() - entry.timestamp > TTL_MS) {\n cache.delete(spreadsheetId);\n return undefined;\n }\n\n return entry.sheets.get(sheetName);\n}\n\nexport function setCachedSheetMetadata(\n spreadsheetId: string,\n sheets: Array<{ title: string; sheetId: number }>,\n): void {\n const sheetsMap = new Map<string, SheetMetadata>();\n for (const sheet of sheets) {\n sheetsMap.set(sheet.title, { sheetId: sheet.sheetId, title: sheet.title });\n }\n\n cache.set(spreadsheetId, {\n sheets: sheetsMap,\n timestamp: Date.now(),\n });\n}\n\nexport function clearSheetCache(spreadsheetId?: string): void {\n if (spreadsheetId) {\n cache.delete(spreadsheetId);\n } else {\n cache.clear();\n }\n}\n\nexport function getSheetCacheStats(): { size: number; entries: string[] } {\n return {\n size: cache.size,\n entries: Array.from(cache.keys()),\n };\n}\n", "import { randomUUID } from \"node:crypto\";\nimport type { drive_v3, slides_v1 } from \"googleapis\";\nimport {\n successResponse,\n structuredResponse,\n errorResponse,\n withTimeout,\n validateArgs,\n} from \"../utils/index.js\";\nimport { GOOGLE_MIME_TYPES, getMimeTypeSuggestion } from \"../utils/mimeTypes.js\";\nimport type { ToolResponse } from \"../utils/index.js\";\nimport {\n ListSlidePagesSchema,\n CreateGoogleSlidesSchema,\n UpdateGoogleSlidesSchema,\n GetGoogleSlidesContentSchema,\n CreateGoogleSlidesTextBoxSchema,\n CreateGoogleSlidesShapeSchema,\n SlidesSpeakerNotesSchema,\n FormatSlidesTextSchema,\n FormatSlidesShapeSchema,\n FormatSlideBackgroundSchema,\n} from \"../schemas/index.js\";\nimport { resolveOptionalFolderPath, checkFileExists } from \"./helpers.js\";\nimport { toSlidesColorStyle, toSlidesSolidFill } from \"../utils/colors.js\";\n\nexport async function handleCreateGoogleSlides(\n drive: drive_v3.Drive,\n slides: slides_v1.Slides,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(CreateGoogleSlidesSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n const parentFolderId = await resolveOptionalFolderPath(\n drive,\n data.parentFolderId,\n data.parentPath,\n );\n\n // Check if presentation already exists\n const existingFileId = await checkFileExists(drive, data.name, parentFolderId);\n if (existingFileId) {\n return errorResponse(\n `A presentation named \"${data.name}\" already exists in this location. ` +\n `File ID: ${existingFileId}. To modify it, you can use Google Slides directly.`,\n );\n }\n\n // API call 1: Create presentation\n const presentation = await slides.presentations.create({\n requestBody: { title: data.name },\n });\n\n // API call 2: Move to folder\n await drive.files.update({\n fileId: presentation.data.presentationId!,\n addParents: parentFolderId,\n removeParents: \"root\",\n supportsAllDrives: true,\n });\n\n // Generate all slide IDs upfront\n const slideIds = data.slides.map(() => `slide_${randomUUID().substring(0, 8)}`);\n\n // API call 3: Batch create all slides at once\n const createSlideRequests: slides_v1.Schema$Request[] = slideIds.map((slideObjectId) => ({\n createSlide: {\n objectId: slideObjectId,\n slideLayoutReference: { predefinedLayout: \"TITLE_AND_BODY\" },\n },\n }));\n\n await slides.presentations.batchUpdate({\n presentationId: presentation.data.presentationId!,\n requestBody: { requests: createSlideRequests },\n });\n\n // API call 4: Fetch all slides to get placeholder IDs\n const updatedPresentation = await slides.presentations.get({\n presentationId: presentation.data.presentationId!,\n });\n\n // Build insert text requests for all slides\n const insertTextRequests: slides_v1.Schema$Request[] = [];\n\n // Note: The first slide in the response is the default blank slide created with the presentation\n // Our custom slides start at index 1\n for (let i = 0; i < data.slides.length; i++) {\n const slide = data.slides[i];\n // Our slides start at index 1 (after the default blank slide)\n const presentationSlide = updatedPresentation.data.slides?.[i + 1];\n\n if (presentationSlide?.pageElements) {\n for (const el of presentationSlide.pageElements) {\n if (el.shape?.placeholder?.type === \"TITLE\" && el.objectId) {\n insertTextRequests.push({\n insertText: {\n objectId: el.objectId,\n text: slide.title,\n insertionIndex: 0,\n },\n });\n } else if (el.shape?.placeholder?.type === \"BODY\" && el.objectId) {\n insertTextRequests.push({\n insertText: {\n objectId: el.objectId,\n text: slide.content,\n insertionIndex: 0,\n },\n });\n }\n }\n }\n }\n\n // API call 5: Batch insert all text at once\n if (insertTextRequests.length > 0) {\n await slides.presentations.batchUpdate({\n presentationId: presentation.data.presentationId!,\n requestBody: { requests: insertTextRequests },\n });\n }\n\n return successResponse(\n `Created Google Slides presentation: ${data.name}\\n` +\n `ID: ${presentation.data.presentationId}\\n` +\n `Link: https://docs.google.com/presentation/d/${presentation.data.presentationId}`,\n );\n}\n\nexport async function handleUpdateGoogleSlides(\n slides: slides_v1.Slides,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(UpdateGoogleSlidesSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // API call 1: Get current presentation details\n const currentPresentation = await slides.presentations.get({\n presentationId: data.presentationId,\n });\n\n if (!currentPresentation.data.slides) {\n return errorResponse(\n `No slides found in presentation ${data.presentationId}. ` +\n `The presentation may be empty or inaccessible.`,\n );\n }\n\n if (data.slides.length === 0) {\n return errorResponse(\"At least one slide must be provided\");\n }\n\n // Collect all slide IDs except the first one (we'll keep it for now)\n const slideIdsToDelete = currentPresentation.data.slides\n .slice(1)\n .map((slide) => slide.objectId)\n .filter((id): id is string => id !== undefined);\n\n // Prepare all requests for a single batch update\n const requests: slides_v1.Schema$Request[] = [];\n\n // Delete all slides except the first one\n for (const slideId of slideIdsToDelete) {\n requests.push({ deleteObject: { objectId: slideId } });\n }\n\n // Clear content of the first slide\n const firstSlide = currentPresentation.data.slides[0];\n if (firstSlide?.pageElements) {\n for (const element of firstSlide.pageElements) {\n if (element.objectId && element.shape?.text) {\n requests.push({\n deleteText: {\n objectId: element.objectId,\n textRange: { type: \"ALL\" },\n },\n });\n }\n }\n }\n\n // Update the first slide with new content\n const firstSlideContent = data.slides[0];\n if (firstSlide?.pageElements) {\n let titlePlaceholderId: string | undefined;\n let bodyPlaceholderId: string | undefined;\n\n for (const element of firstSlide.pageElements) {\n if (\n element.shape?.placeholder?.type === \"TITLE\" ||\n element.shape?.placeholder?.type === \"CENTERED_TITLE\"\n ) {\n titlePlaceholderId = element.objectId || undefined;\n } else if (\n element.shape?.placeholder?.type === \"BODY\" ||\n element.shape?.placeholder?.type === \"SUBTITLE\"\n ) {\n bodyPlaceholderId = element.objectId || undefined;\n }\n }\n\n if (titlePlaceholderId) {\n requests.push({\n insertText: {\n objectId: titlePlaceholderId,\n text: firstSlideContent.title,\n insertionIndex: 0,\n },\n });\n }\n\n if (bodyPlaceholderId) {\n requests.push({\n insertText: {\n objectId: bodyPlaceholderId,\n text: firstSlideContent.content,\n insertionIndex: 0,\n },\n });\n }\n }\n\n // For additional slides, use placeholderIdMappings to set known IDs upfront\n // This avoids needing a second API call to fetch placeholder IDs\n const newSlideData: Array<{\n slideId: string;\n titleId: string;\n bodyId: string;\n }> = [];\n\n for (let i = 1; i < data.slides.length; i++) {\n const slideId = `slide_${Date.now()}_${i}`;\n const titleId = `title_${Date.now()}_${i}`;\n const bodyId = `body_${Date.now()}_${i}`;\n\n newSlideData.push({ slideId, titleId, bodyId });\n\n requests.push({\n createSlide: {\n objectId: slideId,\n slideLayoutReference: { predefinedLayout: \"TITLE_AND_BODY\" },\n placeholderIdMappings: [\n {\n layoutPlaceholder: { type: \"TITLE\" },\n objectId: titleId,\n },\n {\n layoutPlaceholder: { type: \"BODY\" },\n objectId: bodyId,\n },\n ],\n },\n });\n }\n\n // Add insertText requests for all additional slides using our pre-assigned IDs\n for (let i = 0; i < newSlideData.length; i++) {\n const slideContent = data.slides[i + 1];\n const { titleId, bodyId } = newSlideData[i];\n\n requests.push({\n insertText: {\n objectId: titleId,\n text: slideContent.title,\n insertionIndex: 0,\n },\n });\n requests.push({\n insertText: {\n objectId: bodyId,\n text: slideContent.content,\n insertionIndex: 0,\n },\n });\n }\n\n // API call 2: Execute single batch update with all operations\n await slides.presentations.batchUpdate({\n presentationId: data.presentationId,\n requestBody: { requests },\n });\n\n return successResponse(\n `Updated Google Slides presentation with ${data.slides.length} slide(s)\\n` +\n `Link: https://docs.google.com/presentation/d/${data.presentationId}`,\n );\n}\n\nexport async function handleGetGoogleSlidesContent(\n drive: drive_v3.Drive,\n slides: slides_v1.Slides,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(GetGoogleSlidesContentSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Check file type before calling Slides API to provide helpful error messages\n const metadata = await drive.files.get({\n fileId: data.presentationId,\n fields: \"mimeType,name\",\n supportsAllDrives: true,\n });\n\n const mimeType = metadata.data.mimeType;\n if (mimeType !== GOOGLE_MIME_TYPES.PRESENTATION) {\n const fileName = metadata.data.name || data.presentationId;\n const suggestion = getMimeTypeSuggestion(mimeType);\n return errorResponse(\n `\"${fileName}\" is not a Google Slides presentation (type: ${mimeType}). ${suggestion}`,\n );\n }\n\n const presentation = await withTimeout(\n slides.presentations.get({\n presentationId: data.presentationId,\n }),\n 30000,\n \"Get presentation content\",\n );\n\n if (!presentation.data.slides) {\n return errorResponse(\n `No slides found in presentation ${data.presentationId}. ` +\n `The presentation may be empty or inaccessible.`,\n );\n }\n\n let content = \"Presentation content with element IDs:\\n\\n\";\n const slidesToShow =\n data.slideIndex !== undefined\n ? [presentation.data.slides[data.slideIndex]]\n : presentation.data.slides;\n\n interface SlideElement {\n objectId: string;\n type: string;\n text?: string;\n shapeType?: string;\n }\n\n interface SlideData {\n index: number;\n objectId: string;\n elements: SlideElement[];\n }\n\n const structuredSlides: SlideData[] = [];\n\n slidesToShow.forEach((slide, index) => {\n if (!slide || !slide.objectId) return;\n\n const slideIndex = data.slideIndex ?? index;\n content += `\\nSlide ${slideIndex} (ID: ${slide.objectId}):\\n`;\n content += \"----------------------------\\n\";\n\n const slideData: SlideData = {\n index: slideIndex,\n objectId: slide.objectId,\n elements: [],\n };\n\n if (slide.pageElements) {\n slide.pageElements.forEach((element) => {\n if (!element.objectId) return;\n\n if (element.shape?.text) {\n content += ` Text Box (ID: ${element.objectId}):\\n`;\n const textElements = element.shape.text.textElements || [];\n let text = \"\";\n textElements.forEach((textElement) => {\n if (textElement.textRun?.content) {\n text += textElement.textRun.content;\n }\n });\n content += ` \"${text.trim()}\"\\n`;\n slideData.elements.push({\n objectId: element.objectId,\n type: \"textBox\",\n text: text.trim(),\n });\n } else if (element.shape) {\n content += ` Shape (ID: ${element.objectId}): ${element.shape.shapeType || \"Unknown\"}\\n`;\n slideData.elements.push({\n objectId: element.objectId,\n type: \"shape\",\n shapeType: element.shape.shapeType || undefined,\n });\n } else if (element.image) {\n content += ` Image (ID: ${element.objectId})\\n`;\n slideData.elements.push({\n objectId: element.objectId,\n type: \"image\",\n });\n } else if (element.video) {\n content += ` Video (ID: ${element.objectId})\\n`;\n slideData.elements.push({\n objectId: element.objectId,\n type: \"video\",\n });\n } else if (element.table) {\n content += ` Table (ID: ${element.objectId})\\n`;\n slideData.elements.push({\n objectId: element.objectId,\n type: \"table\",\n });\n }\n });\n }\n\n structuredSlides.push(slideData);\n });\n\n return structuredResponse(content, {\n presentationId: data.presentationId,\n title: presentation.data.title,\n slideCount: presentation.data.slides?.length || 0,\n slides: structuredSlides,\n });\n}\n\nexport async function handleCreateGoogleSlidesTextBox(\n slides: slides_v1.Slides,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(CreateGoogleSlidesTextBoxSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n const elementId = `textBox_${randomUUID().substring(0, 8)}`;\n\n const requests: slides_v1.Schema$Request[] = [\n {\n createShape: {\n objectId: elementId,\n shapeType: \"TEXT_BOX\",\n elementProperties: {\n pageObjectId: data.pageObjectId,\n size: {\n width: { magnitude: data.width, unit: \"EMU\" },\n height: { magnitude: data.height, unit: \"EMU\" },\n },\n transform: {\n scaleX: 1,\n scaleY: 1,\n translateX: data.x,\n translateY: data.y,\n unit: \"EMU\",\n },\n },\n },\n },\n {\n insertText: {\n objectId: elementId,\n text: data.text,\n insertionIndex: 0,\n },\n },\n ];\n\n // Apply optional formatting\n if (data.fontSize || data.bold || data.italic) {\n const textStyle: Record<string, unknown> = {};\n const fields: string[] = [];\n\n if (data.fontSize) {\n textStyle.fontSize = { magnitude: data.fontSize, unit: \"PT\" };\n fields.push(\"fontSize\");\n }\n\n if (data.bold !== undefined) {\n textStyle.bold = data.bold;\n fields.push(\"bold\");\n }\n\n if (data.italic !== undefined) {\n textStyle.italic = data.italic;\n fields.push(\"italic\");\n }\n\n if (fields.length > 0) {\n requests.push({\n updateTextStyle: {\n objectId: elementId,\n style: textStyle,\n fields: fields.join(\",\"),\n textRange: { type: \"ALL\" },\n },\n });\n }\n }\n\n await slides.presentations.batchUpdate({\n presentationId: data.presentationId,\n requestBody: { requests },\n });\n\n return successResponse(`Created text box with ID: ${elementId}`);\n}\n\nexport async function handleCreateGoogleSlidesShape(\n slides: slides_v1.Slides,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(CreateGoogleSlidesShapeSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n const elementId = `shape_${randomUUID().substring(0, 8)}`;\n\n const requests: slides_v1.Schema$Request[] = [\n {\n createShape: {\n objectId: elementId,\n shapeType: data.shapeType,\n elementProperties: {\n pageObjectId: data.pageObjectId,\n size: {\n width: { magnitude: data.width, unit: \"EMU\" },\n height: { magnitude: data.height, unit: \"EMU\" },\n },\n transform: {\n scaleX: 1,\n scaleY: 1,\n translateX: data.x,\n translateY: data.y,\n unit: \"EMU\",\n },\n },\n },\n },\n ];\n\n // Apply background color if specified\n if (data.backgroundColor) {\n requests.push({\n updateShapeProperties: {\n objectId: elementId,\n shapeProperties: {\n shapeBackgroundFill: {\n solidFill: {\n color: {\n rgbColor: {\n red: data.backgroundColor.red || 0,\n green: data.backgroundColor.green || 0,\n blue: data.backgroundColor.blue || 0,\n },\n },\n alpha: data.backgroundColor.alpha || 1,\n },\n },\n },\n fields: \"shapeBackgroundFill\",\n },\n });\n }\n\n await slides.presentations.batchUpdate({\n presentationId: data.presentationId,\n requestBody: { requests },\n });\n\n return successResponse(`Created ${data.shapeType} shape with ID: ${elementId}`);\n}\n\n/**\n * Unified speaker notes handler - get or update notes\n */\nexport async function handleSlidesSpeakerNotes(\n slides: slides_v1.Slides,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(SlidesSpeakerNotesSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Get the presentation to access the slide\n const presentation = await slides.presentations.get({\n presentationId: data.presentationId,\n });\n\n const slideCount = presentation.data.slides?.length || 0;\n if (!presentation.data.slides || data.slideIndex < 0 || data.slideIndex >= slideCount) {\n return errorResponse(\n `Slide index ${data.slideIndex} is invalid. Valid range: 0 to ${slideCount - 1} (presentation has ${slideCount} slides)`,\n );\n }\n\n const slide = presentation.data.slides[data.slideIndex];\n const notesObjectId = slide.slideProperties?.notesPage?.notesProperties?.speakerNotesObjectId;\n\n if (data.action === \"get\") {\n return getSpeakerNotes(slide, notesObjectId);\n } else {\n return updateSpeakerNotes(slides, data.presentationId, slide, notesObjectId, data.notes!);\n }\n}\n\nfunction getSpeakerNotes(\n slide: slides_v1.Schema$Page,\n notesObjectId: string | null | undefined,\n): ToolResponse {\n if (!notesObjectId) {\n return successResponse(\"No speaker notes found for this slide\");\n }\n\n const notesPage = slide.slideProperties?.notesPage;\n if (!notesPage || !notesPage.pageElements) {\n return successResponse(\"No speaker notes found for this slide\");\n }\n\n const speakerNotesElement = notesPage.pageElements.find(\n (element) => element.objectId === notesObjectId,\n );\n\n if (!speakerNotesElement || !speakerNotesElement.shape?.text) {\n return successResponse(\"No speaker notes found for this slide\");\n }\n\n let notesText = \"\";\n const textElements = speakerNotesElement.shape.text.textElements || [];\n textElements.forEach((textElement) => {\n if (textElement.textRun?.content) {\n notesText += textElement.textRun.content;\n }\n });\n\n return successResponse(notesText.trim() || \"No speaker notes found for this slide\");\n}\n\nasync function updateSpeakerNotes(\n slidesApi: slides_v1.Slides,\n presentationId: string,\n slide: slides_v1.Schema$Page,\n notesObjectId: string | null | undefined,\n notes: string,\n): Promise<ToolResponse> {\n if (!notesObjectId) {\n return errorResponse(\n \"This slide does not have a speaker notes object. \" +\n \"Speaker notes may need to be initialized manually in Google Slides first.\",\n );\n }\n\n const notesPage = slide.slideProperties?.notesPage;\n const speakerNotesElement = notesPage?.pageElements?.find(\n (element) => element.objectId === notesObjectId,\n );\n\n const hasExistingText = speakerNotesElement?.shape?.text?.textElements?.some(\n (el) => el.textRun?.content && el.textRun.content.trim().length > 0,\n );\n\n const requests: slides_v1.Schema$Request[] = [];\n\n if (hasExistingText) {\n requests.push({\n deleteText: {\n objectId: notesObjectId,\n textRange: { type: \"ALL\" },\n },\n });\n }\n\n requests.push({\n insertText: {\n objectId: notesObjectId,\n text: notes,\n insertionIndex: 0,\n },\n });\n\n await slidesApi.presentations.batchUpdate({\n presentationId,\n requestBody: { requests },\n });\n\n return successResponse(`Successfully updated speaker notes for slide`);\n}\n\n/**\n * Format text in a slides element (character and paragraph styling)\n */\nexport async function handleFormatSlidesText(\n slides: slides_v1.Slides,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(FormatSlidesTextSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n const requests: slides_v1.Schema$Request[] = [];\n const appliedFormats: string[] = [];\n\n // Character formatting\n const textStyle: Record<string, unknown> = {};\n const textFields: string[] = [];\n\n if (data.bold !== undefined) {\n textStyle.bold = data.bold;\n textFields.push(\"bold\");\n }\n if (data.italic !== undefined) {\n textStyle.italic = data.italic;\n textFields.push(\"italic\");\n }\n if (data.underline !== undefined) {\n textStyle.underline = data.underline;\n textFields.push(\"underline\");\n }\n if (data.strikethrough !== undefined) {\n textStyle.strikethrough = data.strikethrough;\n textFields.push(\"strikethrough\");\n }\n if (data.fontSize !== undefined) {\n textStyle.fontSize = { magnitude: data.fontSize, unit: \"PT\" };\n textFields.push(\"fontSize\");\n }\n if (data.fontFamily !== undefined) {\n textStyle.fontFamily = data.fontFamily;\n textFields.push(\"fontFamily\");\n }\n if (data.foregroundColor) {\n textStyle.foregroundColor = {\n opaqueColor: toSlidesColorStyle(data.foregroundColor),\n };\n textFields.push(\"foregroundColor\");\n }\n\n if (textFields.length > 0) {\n requests.push({\n updateTextStyle: {\n objectId: data.objectId,\n style: textStyle,\n fields: textFields.join(\",\"),\n textRange:\n data.startIndex !== undefined && data.endIndex !== undefined\n ? {\n type: \"FIXED_RANGE\",\n startIndex: data.startIndex,\n endIndex: data.endIndex,\n }\n : { type: \"ALL\" },\n },\n });\n appliedFormats.push(\"text style\");\n }\n\n // Paragraph formatting\n if (data.alignment) {\n requests.push({\n updateParagraphStyle: {\n objectId: data.objectId,\n style: { alignment: data.alignment },\n fields: \"alignment\",\n },\n });\n appliedFormats.push(\"alignment\");\n }\n\n if (data.lineSpacing !== undefined) {\n requests.push({\n updateParagraphStyle: {\n objectId: data.objectId,\n style: { lineSpacing: data.lineSpacing },\n fields: \"lineSpacing\",\n },\n });\n appliedFormats.push(\"line spacing\");\n }\n\n if (data.bulletStyle) {\n if (data.bulletStyle === \"NONE\") {\n requests.push({ deleteParagraphBullets: { objectId: data.objectId } });\n } else if (data.bulletStyle === \"NUMBERED\") {\n requests.push({\n createParagraphBullets: {\n objectId: data.objectId,\n bulletPreset: \"NUMBERED_DIGIT_ALPHA_ROMAN\",\n },\n });\n } else {\n requests.push({\n createParagraphBullets: {\n objectId: data.objectId,\n bulletPreset: `BULLET_${data.bulletStyle}_CIRCLE_SQUARE`,\n },\n });\n }\n appliedFormats.push(\"bullet style\");\n }\n\n if (requests.length === 0) {\n return errorResponse(\n \"No formatting options specified. Provide bold, italic, underline, strikethrough, \" +\n \"fontSize, fontFamily, foregroundColor, alignment, lineSpacing, or bulletStyle.\",\n );\n }\n\n await slides.presentations.batchUpdate({\n presentationId: data.presentationId,\n requestBody: { requests },\n });\n\n return successResponse(`Formatted text ${data.objectId}: ${appliedFormats.join(\", \")}`);\n}\n\n/**\n * Format shape styling (fill and outline)\n */\nexport async function handleFormatSlidesShape(\n slides: slides_v1.Slides,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(FormatSlidesShapeSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n const shapeProperties: Record<string, unknown> = {};\n const fields: string[] = [];\n const appliedFormats: string[] = [];\n\n if (data.backgroundColor) {\n shapeProperties.shapeBackgroundFill = toSlidesSolidFill(data.backgroundColor);\n fields.push(\"shapeBackgroundFill\");\n appliedFormats.push(\"background color\");\n }\n\n const outline: Record<string, unknown> = {};\n let hasOutlineChanges = false;\n\n if (data.outlineColor) {\n outline.outlineFill = {\n solidFill: {\n color: toSlidesColorStyle(data.outlineColor),\n },\n };\n hasOutlineChanges = true;\n appliedFormats.push(\"outline color\");\n }\n\n if (data.outlineWeight !== undefined) {\n outline.weight = { magnitude: data.outlineWeight, unit: \"PT\" };\n hasOutlineChanges = true;\n appliedFormats.push(\"outline weight\");\n }\n\n if (data.outlineDashStyle !== undefined) {\n outline.dashStyle = data.outlineDashStyle;\n hasOutlineChanges = true;\n appliedFormats.push(\"outline dash style\");\n }\n\n if (hasOutlineChanges) {\n shapeProperties.outline = outline;\n fields.push(\"outline\");\n }\n\n if (fields.length === 0) {\n return errorResponse(\n \"No formatting options specified. Provide backgroundColor, outlineColor, \" +\n \"outlineWeight, or outlineDashStyle.\",\n );\n }\n\n await slides.presentations.batchUpdate({\n presentationId: data.presentationId,\n requestBody: {\n requests: [\n {\n updateShapeProperties: {\n objectId: data.objectId,\n shapeProperties,\n fields: fields.join(\",\"),\n },\n },\n ],\n },\n });\n\n return successResponse(`Formatted shape ${data.objectId}: ${appliedFormats.join(\", \")}`);\n}\n\n/**\n * Set slide background color\n */\nexport async function handleFormatSlideBackground(\n slides: slides_v1.Slides,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(FormatSlideBackgroundSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n const requests = data.pageObjectIds.map((pageObjectId) => ({\n updatePageProperties: {\n objectId: pageObjectId,\n pageProperties: {\n pageBackgroundFill: toSlidesSolidFill(data.backgroundColor),\n },\n fields: \"pageBackgroundFill\",\n },\n }));\n\n await slides.presentations.batchUpdate({\n presentationId: data.presentationId,\n requestBody: { requests },\n });\n\n return successResponse(`Set background color for ${data.pageObjectIds.length} slide(s)`);\n}\n\nexport async function handleListSlidePages(\n slides: slides_v1.Slides,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(ListSlidePagesSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n const response = await slides.presentations.get({\n presentationId: data.presentationId,\n fields: \"presentationId,slides(objectId,slideProperties(layoutObjectId))\",\n });\n\n const pages =\n response.data.slides?.map((slide, index) => ({\n objectId: slide.objectId,\n index,\n pageType: \"SLIDE\" as const,\n })) || [];\n\n const pageList = pages.map((p) => `${p.index}: ${p.objectId}`).join(\"\\n\");\n\n return structuredResponse(`Presentation has ${pages.length} slide(s):\\n${pageList}`, {\n presentationId: data.presentationId,\n pages,\n });\n}\n", "import type { drive_v3, docs_v1, sheets_v4, slides_v1 } from \"googleapis\";\nimport { structuredResponse, errorResponse, validateArgs } from \"../utils/index.js\";\nimport type { ToolResponse } from \"../utils/index.js\";\nimport { CreateFileSchema, UpdateFileSchema, GetFileContentSchema } from \"../schemas/unified.js\";\nimport { resolveOptionalFolderPath, resolveFileIdFromPath } from \"./helpers.js\";\nimport {\n GOOGLE_MIME_TYPES,\n TEXT_MIME_TYPES,\n EXTENSION_TO_TYPE,\n type FileType,\n getExtension,\n} from \"../utils/mimeTypes.js\";\n\n/**\n * Infer file type from name extension or content structure\n */\nfunction inferFileType(name: string, content: unknown, explicitType?: FileType): FileType {\n // Explicit type takes precedence\n if (explicitType) return explicitType;\n\n // Check extension\n const ext = getExtension(name);\n if (EXTENSION_TO_TYPE[ext]) {\n return EXTENSION_TO_TYPE[ext];\n }\n\n // Infer from content structure\n if (Array.isArray(content)) {\n // Check if it's a 2D array (sheet data)\n if (content.length > 0 && Array.isArray(content[0])) {\n return \"sheet\";\n }\n // Check if it's slides array\n if (\n content.length > 0 &&\n typeof content[0] === \"object\" &&\n \"title\" in content[0] &&\n \"content\" in content[0]\n ) {\n return \"slides\";\n }\n }\n\n // Default to doc for string content\n return \"doc\";\n}\n\n/**\n * Get file type from MIME type\n */\nfunction getTypeFromMime(mimeType: string): FileType | \"binary\" {\n switch (mimeType) {\n case GOOGLE_MIME_TYPES.DOCUMENT:\n return \"doc\";\n case GOOGLE_MIME_TYPES.SPREADSHEET:\n return \"sheet\";\n case GOOGLE_MIME_TYPES.PRESENTATION:\n return \"slides\";\n case TEXT_MIME_TYPES.PLAIN:\n case TEXT_MIME_TYPES.MARKDOWN:\n return \"text\";\n default:\n if (mimeType.startsWith(\"text/\")) return \"text\";\n return \"binary\";\n }\n}\n\n/**\n * Smart file creation that routes to appropriate handler based on type inference.\n */\nexport async function handleCreateFile(\n drive: drive_v3.Drive,\n docs: docs_v1.Docs,\n sheets: sheets_v4.Sheets,\n slides: slides_v1.Slides,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(CreateFileSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Resolve parent folder\n const parentFolderId = await resolveOptionalFolderPath(\n drive,\n data.parentFolderId,\n data.parentPath,\n );\n\n // Infer file type\n const fileType = inferFileType(data.name, data.content, data.type);\n\n switch (fileType) {\n case \"doc\": {\n const content =\n typeof data.content === \"string\" ? data.content : JSON.stringify(data.content);\n\n // Create Google Doc\n const doc = await drive.files.create({\n requestBody: {\n name: data.name,\n mimeType: GOOGLE_MIME_TYPES.DOCUMENT,\n parents: [parentFolderId],\n },\n supportsAllDrives: true,\n });\n\n // Insert content\n if (content) {\n await docs.documents.batchUpdate({\n documentId: doc.data.id!,\n requestBody: {\n requests: [\n { insertText: { location: { index: 1 }, text: content } },\n {\n updateParagraphStyle: {\n range: { startIndex: 1, endIndex: content.length + 1 },\n paragraphStyle: { namedStyleType: \"NORMAL_TEXT\" },\n fields: \"namedStyleType\",\n },\n },\n ],\n },\n });\n }\n\n return structuredResponse(`Created Google Doc: ${data.name}\\nID: ${doc.data.id}`, {\n id: doc.data.id,\n name: data.name,\n type: \"doc\",\n mimeType: GOOGLE_MIME_TYPES.DOCUMENT,\n webViewLink: `https://docs.google.com/document/d/${doc.data.id}/edit`,\n });\n }\n\n case \"sheet\": {\n // Ensure content is 2D array\n let sheetData: string[][];\n if (Array.isArray(data.content) && Array.isArray(data.content[0])) {\n sheetData = data.content as string[][];\n } else if (typeof data.content === \"string\") {\n // Parse CSV-like string\n sheetData = data.content.split(\"\\n\").map((row) => row.split(\",\"));\n } else {\n return errorResponse(\"Sheet content must be a 2D array or CSV string\");\n }\n\n // Create spreadsheet\n const spreadsheet = await sheets.spreadsheets.create({\n requestBody: {\n properties: { title: data.name },\n sheets: [\n {\n properties: {\n sheetId: 0,\n title: \"Sheet1\",\n gridProperties: {\n rowCount: Math.max(1000, sheetData.length),\n columnCount: 26,\n },\n },\n },\n ],\n },\n });\n\n // Move to folder\n await drive.files.update({\n fileId: spreadsheet.data.spreadsheetId!,\n addParents: parentFolderId,\n removeParents: \"root\",\n supportsAllDrives: true,\n });\n\n // Populate data\n if (sheetData.length > 0) {\n await sheets.spreadsheets.values.update({\n spreadsheetId: spreadsheet.data.spreadsheetId!,\n range: \"Sheet1!A1\",\n valueInputOption: \"RAW\",\n requestBody: { values: sheetData },\n });\n }\n\n return structuredResponse(\n `Created Google Sheet: ${data.name}\\nID: ${spreadsheet.data.spreadsheetId}`,\n {\n id: spreadsheet.data.spreadsheetId,\n name: data.name,\n type: \"sheet\",\n mimeType: GOOGLE_MIME_TYPES.SPREADSHEET,\n webViewLink: spreadsheet.data.spreadsheetUrl,\n },\n );\n }\n\n case \"slides\": {\n // Ensure content is slides array\n let slidesData: Array<{ title: string; content: string }>;\n if (\n Array.isArray(data.content) &&\n data.content.length > 0 &&\n typeof data.content[0] === \"object\" &&\n !Array.isArray(data.content[0]) &&\n \"title\" in data.content[0]\n ) {\n slidesData = data.content as Array<{ title: string; content: string }>;\n } else if (typeof data.content === \"string\") {\n // Create single slide with content\n slidesData = [{ title: data.name, content: data.content }];\n } else {\n return errorResponse(\"Slides content must be an array of {title, content} objects\");\n }\n\n // Create presentation\n const presentation = await slides.presentations.create({\n requestBody: { title: data.name },\n });\n\n // Move to folder\n await drive.files.update({\n fileId: presentation.data.presentationId!,\n addParents: parentFolderId,\n removeParents: \"root\",\n supportsAllDrives: true,\n });\n\n // Add slides (simplified - would need full implementation for content)\n if (slidesData.length > 0) {\n const { randomUUID } = await import(\"node:crypto\");\n const slideIds = slidesData.map(() => `slide_${randomUUID().substring(0, 8)}`);\n\n await slides.presentations.batchUpdate({\n presentationId: presentation.data.presentationId!,\n requestBody: {\n requests: slideIds.map((id) => ({\n createSlide: {\n objectId: id,\n slideLayoutReference: { predefinedLayout: \"TITLE_AND_BODY\" },\n },\n })),\n },\n });\n }\n\n return structuredResponse(\n `Created Google Slides: ${data.name}\\nID: ${presentation.data.presentationId}`,\n {\n id: presentation.data.presentationId,\n name: data.name,\n type: \"slides\",\n mimeType: GOOGLE_MIME_TYPES.PRESENTATION,\n webViewLink: `https://docs.google.com/presentation/d/${presentation.data.presentationId}/edit`,\n },\n );\n }\n\n case \"text\": {\n const content =\n typeof data.content === \"string\" ? data.content : JSON.stringify(data.content);\n const mimeType = data.name.endsWith(\".md\") ? TEXT_MIME_TYPES.MARKDOWN : TEXT_MIME_TYPES.PLAIN;\n\n const file = await drive.files.create({\n requestBody: {\n name: data.name,\n mimeType,\n parents: [parentFolderId],\n },\n media: {\n mimeType,\n body: content,\n },\n supportsAllDrives: true,\n });\n\n return structuredResponse(`Created text file: ${data.name}\\nID: ${file.data.id}`, {\n id: file.data.id,\n name: data.name,\n type: \"text\",\n mimeType,\n webViewLink: file.data.webViewLink,\n });\n }\n }\n}\n\n/**\n * Smart file update that detects file type and routes accordingly.\n */\nexport async function handleUpdateFile(\n drive: drive_v3.Drive,\n docs: docs_v1.Docs,\n sheets: sheets_v4.Sheets,\n _slides: slides_v1.Slides,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(UpdateFileSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Resolve file ID\n const fileId = await resolveFileIdFromPath(drive, data.fileId, data.filePath);\n\n // Get file metadata to determine type\n const file = await drive.files.get({\n fileId,\n fields: \"name, mimeType\",\n supportsAllDrives: true,\n });\n\n const fileType = getTypeFromMime(file.data.mimeType!);\n\n switch (fileType) {\n case \"doc\": {\n const content =\n typeof data.content === \"string\" ? data.content : JSON.stringify(data.content);\n\n // Get current document to find end index\n const doc = await docs.documents.get({ documentId: fileId });\n const endIndex = doc.data.body?.content?.slice(-1)[0]?.endIndex || 1;\n\n // Replace all content\n await docs.documents.batchUpdate({\n documentId: fileId,\n requestBody: {\n requests: [\n {\n deleteContentRange: {\n range: { startIndex: 1, endIndex: endIndex - 1 },\n },\n },\n { insertText: { location: { index: 1 }, text: content } },\n ],\n },\n });\n\n return structuredResponse(`Updated Google Doc: ${file.data.name}`, {\n id: fileId,\n name: file.data.name,\n type: \"doc\",\n updated: true,\n });\n }\n\n case \"sheet\": {\n let sheetData: string[][];\n if (Array.isArray(data.content) && Array.isArray(data.content[0])) {\n sheetData = data.content as string[][];\n } else if (typeof data.content === \"string\") {\n sheetData = data.content.split(\"\\n\").map((row) => row.split(\",\"));\n } else {\n return errorResponse(\"Sheet content must be a 2D array or CSV string\");\n }\n\n const range = data.range || \"Sheet1!A1\";\n\n await sheets.spreadsheets.values.update({\n spreadsheetId: fileId,\n range,\n valueInputOption: \"RAW\",\n requestBody: { values: sheetData },\n });\n\n return structuredResponse(`Updated Google Sheet: ${file.data.name}`, {\n id: fileId,\n name: file.data.name,\n type: \"sheet\",\n range,\n updated: true,\n });\n }\n\n case \"slides\": {\n return errorResponse(\n \"Updating slides requires the updateGoogleSlides tool for slide-by-slide control. \" +\n \"Use updateGoogleSlides with presentationId and slides array.\",\n );\n }\n\n case \"text\": {\n const content =\n typeof data.content === \"string\" ? data.content : JSON.stringify(data.content);\n\n await drive.files.update({\n fileId,\n media: {\n mimeType: file.data.mimeType!,\n body: content,\n },\n supportsAllDrives: true,\n });\n\n return structuredResponse(`Updated text file: ${file.data.name}`, {\n id: fileId,\n name: file.data.name,\n type: \"text\",\n updated: true,\n });\n }\n\n case \"binary\":\n return errorResponse(\n `Cannot update binary file \"${file.data.name}\" (${file.data.mimeType}). ` +\n \"Use uploadFile to replace the file.\",\n );\n }\n}\n\n/**\n * Smart content retrieval that returns appropriate format based on file type.\n */\nexport async function handleGetFileContent(\n drive: drive_v3.Drive,\n docs: docs_v1.Docs,\n sheets: sheets_v4.Sheets,\n slides: slides_v1.Slides,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(GetFileContentSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Resolve file ID\n const fileId = await resolveFileIdFromPath(drive, data.fileId, data.filePath);\n\n // Get file metadata\n const file = await drive.files.get({\n fileId,\n fields: \"name, mimeType, modifiedTime, size\",\n supportsAllDrives: true,\n });\n\n const fileType = getTypeFromMime(file.data.mimeType!);\n\n switch (fileType) {\n case \"doc\": {\n const doc = await docs.documents.get({ documentId: fileId });\n\n // Extract text content\n let content = \"\";\n const body = doc.data.body?.content || [];\n for (const element of body) {\n if (element.paragraph?.elements) {\n for (const textElement of element.paragraph.elements) {\n if (textElement.textRun?.content) {\n content += textElement.textRun.content;\n }\n }\n }\n }\n\n return structuredResponse(content.trim(), {\n fileId,\n name: file.data.name,\n type: \"doc\",\n mimeType: file.data.mimeType,\n content: content.trim(),\n metadata: {\n modifiedTime: file.data.modifiedTime,\n title: doc.data.title,\n },\n });\n }\n\n case \"sheet\": {\n const range = data.range || \"A:ZZ\";\n\n const response = await sheets.spreadsheets.values.get({\n spreadsheetId: fileId,\n range,\n });\n\n const values = response.data.values || [];\n\n return structuredResponse(\n `Sheet: ${file.data.name}\\nRange: ${range}\\nRows: ${values.length}`,\n {\n fileId,\n name: file.data.name,\n type: \"sheet\",\n mimeType: file.data.mimeType,\n content: values,\n range: response.data.range,\n metadata: {\n modifiedTime: file.data.modifiedTime,\n rowCount: values.length,\n columnCount: values[0]?.length || 0,\n },\n },\n );\n }\n\n case \"slides\": {\n const presentation = await slides.presentations.get({\n presentationId: fileId,\n });\n\n const slideData = (presentation.data.slides || []).map((slide, index) => {\n let title = \"\";\n let content = \"\";\n\n for (const element of slide.pageElements || []) {\n if (element.shape?.text?.textElements) {\n const text = element.shape.text.textElements\n .filter((te) => te.textRun?.content)\n .map((te) => te.textRun!.content)\n .join(\"\");\n\n // First text element with content is likely the title\n if (!title && text.trim()) {\n title = text.trim();\n } else if (text.trim()) {\n content += text;\n }\n }\n }\n\n return {\n index,\n objectId: slide.objectId,\n title: title || `Slide ${index + 1}`,\n content: content.trim(),\n };\n });\n\n return structuredResponse(`Presentation: ${file.data.name}\\nSlides: ${slideData.length}`, {\n fileId,\n name: file.data.name,\n type: \"slides\",\n mimeType: file.data.mimeType,\n content: slideData,\n metadata: {\n modifiedTime: file.data.modifiedTime,\n slideCount: slideData.length,\n title: presentation.data.title,\n },\n });\n }\n\n case \"text\": {\n const response = await drive.files.get(\n { fileId, alt: \"media\", supportsAllDrives: true },\n { responseType: \"text\" },\n );\n\n const content = typeof response.data === \"string\" ? response.data : String(response.data);\n\n return structuredResponse(content, {\n fileId,\n name: file.data.name,\n type: \"text\",\n mimeType: file.data.mimeType,\n content,\n metadata: {\n modifiedTime: file.data.modifiedTime,\n size: file.data.size,\n },\n });\n }\n\n case \"binary\":\n return errorResponse(\n `Cannot read binary file \"${file.data.name}\" (${file.data.mimeType}) as text. ` +\n \"Use downloadFile to download the raw content.\",\n );\n }\n}\n", "import type { calendar_v3 } from \"googleapis\";\nimport { log, successResponse, structuredResponse, validateArgs } from \"../utils/index.js\";\nimport type { ToolResponse } from \"../utils/index.js\";\nimport {\n ListCalendarsSchema,\n ListEventsSchema,\n GetEventSchema,\n CreateEventSchema,\n UpdateEventSchema,\n DeleteEventSchema,\n FindFreeTimeSchema,\n} from \"../schemas/index.js\";\nimport { randomUUID } from \"crypto\";\n\n// Helper to format event datetime for display\nfunction formatEventTime(eventTime: calendar_v3.Schema$EventDateTime | undefined): string {\n if (!eventTime) return \"Unknown\";\n if (eventTime.date) return eventTime.date;\n if (eventTime.dateTime) {\n const date = new Date(eventTime.dateTime);\n return date.toLocaleString();\n }\n return \"Unknown\";\n}\n\n// Helper to format event for text output\nfunction formatEventSummary(event: calendar_v3.Schema$Event): string {\n const start = formatEventTime(event.start);\n const end = formatEventTime(event.end);\n const isAllDay = !!event.start?.date;\n const timeStr = isAllDay ? start : `${start} - ${end}`;\n return `${event.summary || \"(No title)\"} | ${timeStr}`;\n}\n\nexport async function handleListCalendars(\n calendar: calendar_v3.Calendar,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(ListCalendarsSchema, args);\n if (!validation.success) return validation.response;\n const { showHidden, showDeleted } = validation.data;\n\n const response = await calendar.calendarList.list({\n showHidden,\n showDeleted,\n });\n\n const calendars = response.data.items || [];\n\n if (calendars.length === 0) {\n return structuredResponse(\"No calendars found.\", { calendars: [] });\n }\n\n const formattedCalendars = calendars\n .map((cal) => {\n const primary = cal.primary ? \" (Primary)\" : \"\";\n const access = cal.accessRole ? ` [${cal.accessRole}]` : \"\";\n return `${cal.summary || cal.id}${primary}${access} - ID: ${cal.id}`;\n })\n .join(\"\\n\");\n\n log(\"Listed calendars\", { count: calendars.length });\n\n return structuredResponse(`Found ${calendars.length} calendar(s):\\n\\n${formattedCalendars}`, {\n calendars: calendars.map((cal) => ({\n id: cal.id,\n summary: cal.summary,\n description: cal.description,\n primary: cal.primary,\n accessRole: cal.accessRole,\n backgroundColor: cal.backgroundColor,\n foregroundColor: cal.foregroundColor,\n timeZone: cal.timeZone,\n })),\n });\n}\n\nexport async function handleListEvents(\n calendar: calendar_v3.Calendar,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(ListEventsSchema, args);\n if (!validation.success) return validation.response;\n const { calendarId, timeMin, timeMax, query, maxResults, pageToken, singleEvents, orderBy } =\n validation.data;\n\n const response = await calendar.events.list({\n calendarId,\n timeMin,\n timeMax,\n q: query,\n maxResults,\n pageToken,\n singleEvents,\n orderBy,\n });\n\n const events = response.data.items || [];\n\n if (events.length === 0) {\n return structuredResponse(\"No events found.\", {\n events: [],\n nextPageToken: null,\n });\n }\n\n const formattedEvents = events.map((event) => `- ${formatEventSummary(event)}`).join(\"\\n\");\n\n let textResponse = `Found ${events.length} event(s):\\n\\n${formattedEvents}`;\n if (response.data.nextPageToken) {\n textResponse += `\\n\\nMore events available. Use pageToken: ${response.data.nextPageToken}`;\n }\n\n log(\"Listed events\", { calendarId, count: events.length });\n\n return structuredResponse(textResponse, {\n events: events.map((event) => ({\n id: event.id,\n summary: event.summary,\n description: event.description,\n location: event.location,\n start: event.start,\n end: event.end,\n status: event.status,\n htmlLink: event.htmlLink,\n hangoutLink: event.hangoutLink,\n attendees: event.attendees?.map((a) => ({\n email: a.email,\n displayName: a.displayName,\n responseStatus: a.responseStatus,\n optional: a.optional,\n })),\n organizer: event.organizer,\n creator: event.creator,\n recurringEventId: event.recurringEventId,\n })),\n nextPageToken: response.data.nextPageToken || null,\n });\n}\n\nexport async function handleGetEvent(\n calendar: calendar_v3.Calendar,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(GetEventSchema, args);\n if (!validation.success) return validation.response;\n const { calendarId, eventId } = validation.data;\n\n const response = await calendar.events.get({\n calendarId,\n eventId,\n });\n\n const event = response.data;\n\n const attendeeList =\n event.attendees && event.attendees.length > 0\n ? event.attendees.map((a) => ` - ${a.email} (${a.responseStatus || \"unknown\"})`).join(\"\\n\")\n : \" None\";\n\n const meetLink = event.hangoutLink ? `\\nGoogle Meet: ${event.hangoutLink}` : \"\";\n\n const textResponse = [\n `Event: ${event.summary || \"(No title)\"}`,\n `ID: ${event.id}`,\n `Status: ${event.status}`,\n `Start: ${formatEventTime(event.start)}`,\n `End: ${formatEventTime(event.end)}`,\n event.location ? `Location: ${event.location}` : null,\n event.description ? `Description: ${event.description}` : null,\n meetLink,\n `\\nAttendees:\\n${attendeeList}`,\n `\\nOrganizer: ${event.organizer?.email || \"Unknown\"}`,\n `Link: ${event.htmlLink}`,\n ]\n .filter(Boolean)\n .join(\"\\n\");\n\n log(\"Retrieved event\", { calendarId, eventId });\n\n return structuredResponse(textResponse, {\n id: event.id,\n summary: event.summary,\n description: event.description,\n location: event.location,\n start: event.start,\n end: event.end,\n status: event.status,\n htmlLink: event.htmlLink,\n hangoutLink: event.hangoutLink,\n attendees: event.attendees?.map((a) => ({\n email: a.email,\n displayName: a.displayName,\n responseStatus: a.responseStatus,\n optional: a.optional,\n organizer: a.organizer,\n self: a.self,\n })),\n organizer: event.organizer,\n creator: event.creator,\n created: event.created,\n updated: event.updated,\n recurrence: event.recurrence,\n recurringEventId: event.recurringEventId,\n reminders: event.reminders,\n conferenceData: event.conferenceData,\n });\n}\n\nexport async function handleCreateEvent(\n calendar: calendar_v3.Calendar,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(CreateEventSchema, args);\n if (!validation.success) return validation.response;\n const {\n calendarId,\n summary,\n description,\n location,\n start,\n end,\n attendees,\n addGoogleMeet,\n reminders,\n colorId,\n recurrence,\n sendUpdates,\n } = validation.data;\n\n // Build the event request body\n const eventBody: calendar_v3.Schema$Event = {\n summary,\n description,\n location,\n start: {\n dateTime: start.dateTime,\n date: start.date,\n timeZone: start.timeZone,\n },\n end: {\n dateTime: end.dateTime,\n date: end.date,\n timeZone: end.timeZone,\n },\n colorId,\n recurrence,\n };\n\n // Add attendees if provided\n if (attendees && attendees.length > 0) {\n eventBody.attendees = attendees.map((a) => ({\n email: a.email,\n displayName: a.displayName,\n optional: a.optional,\n }));\n }\n\n // Add Google Meet conference if requested\n if (addGoogleMeet) {\n eventBody.conferenceData = {\n createRequest: {\n requestId: randomUUID(),\n conferenceSolutionKey: { type: \"hangoutsMeet\" },\n },\n };\n }\n\n // Add custom reminders if provided\n if (reminders && reminders.length > 0) {\n eventBody.reminders = {\n useDefault: false,\n overrides: reminders.map((r) => ({\n method: r.method,\n minutes: r.minutes,\n })),\n };\n }\n\n const response = await calendar.events.insert({\n calendarId,\n requestBody: eventBody,\n conferenceDataVersion: addGoogleMeet ? 1 : undefined,\n sendUpdates,\n });\n\n const event = response.data;\n const meetLink = event.hangoutLink ? `\\nGoogle Meet: ${event.hangoutLink}` : \"\";\n\n log(\"Created event\", { calendarId, eventId: event.id });\n\n return structuredResponse(\n `Created event: ${event.summary}\\nID: ${event.id}\\nLink: ${event.htmlLink}${meetLink}`,\n {\n id: event.id,\n summary: event.summary,\n start: event.start,\n end: event.end,\n htmlLink: event.htmlLink,\n hangoutLink: event.hangoutLink,\n status: event.status,\n },\n );\n}\n\nexport async function handleUpdateEvent(\n calendar: calendar_v3.Calendar,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(UpdateEventSchema, args);\n if (!validation.success) return validation.response;\n const {\n calendarId,\n eventId,\n summary,\n description,\n location,\n start,\n end,\n attendees,\n addGoogleMeet,\n reminders,\n colorId,\n sendUpdates,\n } = validation.data;\n\n // First get the existing event\n const existingEvent = await calendar.events.get({\n calendarId,\n eventId,\n });\n\n // Build update body, preserving existing values for unspecified fields\n const eventBody: calendar_v3.Schema$Event = {\n ...existingEvent.data,\n summary: summary ?? existingEvent.data.summary,\n description: description ?? existingEvent.data.description,\n location: location ?? existingEvent.data.location,\n colorId: colorId ?? existingEvent.data.colorId,\n };\n\n // Update start/end if provided\n if (start) {\n eventBody.start = {\n dateTime: start.dateTime,\n date: start.date,\n timeZone: start.timeZone,\n };\n }\n if (end) {\n eventBody.end = {\n dateTime: end.dateTime,\n date: end.date,\n timeZone: end.timeZone,\n };\n }\n\n // Update attendees if provided\n if (attendees !== undefined) {\n eventBody.attendees = attendees.map((a) => ({\n email: a.email,\n displayName: a.displayName,\n optional: a.optional,\n }));\n }\n\n // Add Google Meet if requested and not already present\n let conferenceDataVersion: number | undefined;\n if (addGoogleMeet && !existingEvent.data.hangoutLink) {\n eventBody.conferenceData = {\n createRequest: {\n requestId: randomUUID(),\n conferenceSolutionKey: { type: \"hangoutsMeet\" },\n },\n };\n conferenceDataVersion = 1;\n }\n\n // Update reminders if provided\n if (reminders !== undefined) {\n eventBody.reminders = {\n useDefault: false,\n overrides: reminders.map((r) => ({\n method: r.method,\n minutes: r.minutes,\n })),\n };\n }\n\n const response = await calendar.events.update({\n calendarId,\n eventId,\n requestBody: eventBody,\n conferenceDataVersion,\n sendUpdates,\n });\n\n const event = response.data;\n const meetLink = event.hangoutLink ? `\\nGoogle Meet: ${event.hangoutLink}` : \"\";\n\n log(\"Updated event\", { calendarId, eventId });\n\n return structuredResponse(\n `Updated event: ${event.summary}\\nID: ${event.id}\\nLink: ${event.htmlLink}${meetLink}`,\n {\n id: event.id,\n summary: event.summary,\n start: event.start,\n end: event.end,\n htmlLink: event.htmlLink,\n hangoutLink: event.hangoutLink,\n status: event.status,\n },\n );\n}\n\nexport async function handleDeleteEvent(\n calendar: calendar_v3.Calendar,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(DeleteEventSchema, args);\n if (!validation.success) return validation.response;\n const { calendarId, eventId, sendUpdates } = validation.data;\n\n // Get event info before deletion for the response\n const existingEvent = await calendar.events.get({\n calendarId,\n eventId,\n });\n\n const eventSummary = existingEvent.data.summary || \"(No title)\";\n\n await calendar.events.delete({\n calendarId,\n eventId,\n sendUpdates,\n });\n\n log(\"Deleted event\", { calendarId, eventId });\n\n return successResponse(`Deleted event: ${eventSummary} (ID: ${eventId})`);\n}\n\nexport async function handleFindFreeTime(\n calendar: calendar_v3.Calendar,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(FindFreeTimeSchema, args);\n if (!validation.success) return validation.response;\n const { calendarIds, timeMin, timeMax, duration, timeZone } = validation.data;\n\n // Use the freebusy API to get busy times\n const response = await calendar.freebusy.query({\n requestBody: {\n timeMin,\n timeMax,\n timeZone,\n items: calendarIds.map((id) => ({ id })),\n },\n });\n\n const calendarsData = response.data.calendars || {};\n\n // Collect all busy periods across all calendars\n const busyPeriods: Array<{ start: Date; end: Date }> = [];\n\n for (const calId of calendarIds) {\n const calData = calendarsData[calId];\n if (calData?.busy) {\n for (const busy of calData.busy) {\n if (busy.start && busy.end) {\n busyPeriods.push({\n start: new Date(busy.start),\n end: new Date(busy.end),\n });\n }\n }\n }\n }\n\n // Sort busy periods by start time\n busyPeriods.sort((a, b) => a.start.getTime() - b.start.getTime());\n\n // Merge overlapping busy periods\n const mergedBusy: Array<{ start: Date; end: Date }> = [];\n for (const period of busyPeriods) {\n if (mergedBusy.length === 0) {\n mergedBusy.push(period);\n } else {\n const last = mergedBusy[mergedBusy.length - 1];\n if (period.start <= last.end) {\n // Overlapping or adjacent, extend the end\n last.end = new Date(Math.max(last.end.getTime(), period.end.getTime()));\n } else {\n mergedBusy.push(period);\n }\n }\n }\n\n // Find free slots\n const freeSlots: Array<{ start: string; end: string; durationMinutes: number }> = [];\n const rangeStart = new Date(timeMin);\n const rangeEnd = new Date(timeMax);\n const durationMs = duration * 60 * 1000;\n\n let currentTime = rangeStart;\n\n for (const busy of mergedBusy) {\n // Check if there's a gap before this busy period\n if (busy.start > currentTime) {\n const gapDuration = busy.start.getTime() - currentTime.getTime();\n if (gapDuration >= durationMs) {\n freeSlots.push({\n start: currentTime.toISOString(),\n end: busy.start.toISOString(),\n durationMinutes: Math.floor(gapDuration / 60000),\n });\n }\n }\n // Move current time to end of busy period\n currentTime = new Date(Math.max(currentTime.getTime(), busy.end.getTime()));\n }\n\n // Check for free time after last busy period\n if (currentTime < rangeEnd) {\n const gapDuration = rangeEnd.getTime() - currentTime.getTime();\n if (gapDuration >= durationMs) {\n freeSlots.push({\n start: currentTime.toISOString(),\n end: rangeEnd.toISOString(),\n durationMinutes: Math.floor(gapDuration / 60000),\n });\n }\n }\n\n if (freeSlots.length === 0) {\n return structuredResponse(\n `No free slots of ${duration} minutes found in the specified range.`,\n {\n freeSlots: [],\n busyPeriods: mergedBusy.map((p) => ({\n start: p.start.toISOString(),\n end: p.end.toISOString(),\n })),\n },\n );\n }\n\n const formattedSlots = freeSlots\n .map((slot) => {\n const start = new Date(slot.start);\n const end = new Date(slot.end);\n return `- ${start.toLocaleString()} to ${end.toLocaleString()} (${slot.durationMinutes} min)`;\n })\n .join(\"\\n\");\n\n log(\"Found free time slots\", { count: freeSlots.length });\n\n return structuredResponse(\n `Found ${freeSlots.length} free slot(s) of at least ${duration} minutes:\\n\\n${formattedSlots}`,\n {\n freeSlots,\n busyPeriods: mergedBusy.map((p) => ({\n start: p.start.toISOString(),\n end: p.end.toISOString(),\n })),\n },\n );\n}\n", "import type { gmail_v1 } from \"googleapis\";\nimport {\n log,\n successResponse,\n structuredResponse,\n errorResponse,\n validateArgs,\n buildMimeMessage,\n parseEmailHeaders,\n decodeBase64Url,\n truncateResponse,\n} from \"../utils/index.js\";\nimport type { ToolResponse } from \"../utils/index.js\";\nimport {\n SendEmailSchema,\n DraftEmailSchema,\n ReadEmailSchema,\n SearchEmailsSchema,\n DeleteEmailSchema,\n ModifyEmailSchema,\n DownloadAttachmentSchema,\n CreateLabelSchema,\n UpdateLabelSchema,\n DeleteLabelSchema,\n ListLabelsSchema,\n GetOrCreateLabelSchema,\n CreateFilterSchema,\n ListFiltersSchema,\n DeleteFilterSchema,\n} from \"../schemas/index.js\";\nimport * as fs from \"fs/promises\";\nimport * as path from \"path\";\n\n// System labels that cannot be deleted\nconst SYSTEM_LABELS = new Set([\n \"INBOX\",\n \"SPAM\",\n \"TRASH\",\n \"UNREAD\",\n \"STARRED\",\n \"IMPORTANT\",\n \"SENT\",\n \"DRAFT\",\n \"CATEGORY_PERSONAL\",\n \"CATEGORY_SOCIAL\",\n \"CATEGORY_PROMOTIONS\",\n \"CATEGORY_UPDATES\",\n \"CATEGORY_FORUMS\",\n]);\n\n// Helper to extract email body from message parts\nfunction extractEmailBody(payload: gmail_v1.Schema$MessagePart | undefined): {\n text: string;\n html: string;\n} {\n if (!payload) return { text: \"\", html: \"\" };\n\n const result = { text: \"\", html: \"\" };\n\n function processpart(part: gmail_v1.Schema$MessagePart) {\n if (part.mimeType === \"text/plain\" && part.body?.data) {\n result.text = decodeBase64Url(part.body.data);\n } else if (part.mimeType === \"text/html\" && part.body?.data) {\n result.html = decodeBase64Url(part.body.data);\n } else if (part.parts) {\n for (const subPart of part.parts) {\n processpart(subPart);\n }\n }\n }\n\n if (payload.body?.data) {\n if (payload.mimeType === \"text/html\") {\n result.html = decodeBase64Url(payload.body.data);\n } else {\n result.text = decodeBase64Url(payload.body.data);\n }\n }\n\n if (payload.parts) {\n for (const part of payload.parts) {\n processpart(part);\n }\n }\n\n return result;\n}\n\n// Helper to extract attachments info\nfunction extractAttachments(\n payload: gmail_v1.Schema$MessagePart | undefined,\n): Array<{ id: string; filename: string; mimeType: string; size: number }> {\n const attachments: Array<{ id: string; filename: string; mimeType: string; size: number }> = [];\n\n function processPart(part: gmail_v1.Schema$MessagePart) {\n if (part.filename && part.body?.attachmentId) {\n attachments.push({\n id: part.body.attachmentId,\n filename: part.filename,\n mimeType: part.mimeType || \"application/octet-stream\",\n size: part.body.size || 0,\n });\n }\n if (part.parts) {\n for (const subPart of part.parts) {\n processPart(subPart);\n }\n }\n }\n\n if (payload?.parts) {\n for (const part of payload.parts) {\n processPart(part);\n }\n }\n\n return attachments;\n}\n\n// ============================================================================\n// Core Email Operations\n// ============================================================================\n\nexport async function handleSendEmail(gmail: gmail_v1.Gmail, args: unknown): Promise<ToolResponse> {\n const validation = validateArgs(SendEmailSchema, args);\n if (!validation.success) return validation.response;\n const { to, subject, body, html, cc, bcc, replyTo, attachments, threadId, inReplyTo } =\n validation.data;\n\n const raw = buildMimeMessage({\n to,\n subject,\n body,\n html,\n cc,\n bcc,\n replyTo,\n attachments,\n inReplyTo,\n });\n\n const response = await gmail.users.messages.send({\n userId: \"me\",\n requestBody: {\n raw,\n threadId,\n },\n });\n\n log(\"Sent email\", { messageId: response.data.id, threadId: response.data.threadId });\n\n return structuredResponse(\n `Email sent successfully.\\nMessage ID: ${response.data.id}\\nThread ID: ${response.data.threadId}`,\n {\n id: response.data.id,\n threadId: response.data.threadId,\n labelIds: response.data.labelIds,\n },\n );\n}\n\nexport async function handleDraftEmail(\n gmail: gmail_v1.Gmail,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(DraftEmailSchema, args);\n if (!validation.success) return validation.response;\n const { to, subject, body, html, cc, bcc, replyTo, attachments, threadId } = validation.data;\n\n const raw = buildMimeMessage({\n to: to || [],\n subject: subject || \"\",\n body: body || \"\",\n html,\n cc,\n bcc,\n replyTo,\n attachments,\n });\n\n const response = await gmail.users.drafts.create({\n userId: \"me\",\n requestBody: {\n message: {\n raw,\n threadId,\n },\n },\n });\n\n log(\"Created draft\", { draftId: response.data.id });\n\n return structuredResponse(\n `Draft created successfully.\\nDraft ID: ${response.data.id}\\nMessage ID: ${response.data.message?.id}`,\n {\n id: response.data.id,\n messageId: response.data.message?.id,\n threadId: response.data.message?.threadId,\n },\n );\n}\n\nexport async function handleReadEmail(gmail: gmail_v1.Gmail, args: unknown): Promise<ToolResponse> {\n const validation = validateArgs(ReadEmailSchema, args);\n if (!validation.success) return validation.response;\n const { messageId, format, contentFormat } = validation.data;\n\n const response = await gmail.users.messages.get({\n userId: \"me\",\n id: messageId,\n format,\n });\n\n const message = response.data;\n const headers = parseEmailHeaders(message.payload?.headers || []);\n const attachments = extractAttachments(message.payload);\n\n // Extract body based on contentFormat\n let text = \"\";\n let html = \"\";\n if (contentFormat !== \"headers\") {\n const body = extractEmailBody(message.payload);\n text = body.text;\n html = contentFormat === \"full\" ? body.html : \"\";\n }\n\n // Build text output based on contentFormat\n const textOutputParts = [\n `From: ${headers.from || \"Unknown\"}`,\n `To: ${headers.to || \"Unknown\"}`,\n headers.cc ? `Cc: ${headers.cc}` : null,\n `Subject: ${headers.subject || \"(No subject)\"}`,\n `Date: ${headers.date || \"Unknown\"}`,\n `Labels: ${message.labelIds?.join(\", \") || \"None\"}`,\n attachments.length > 0\n ? `Attachments: ${attachments.map((a) => `${a.filename} (${a.size} bytes)`).join(\", \")}`\n : null,\n ];\n\n // Only include body section if contentFormat is not \"headers\"\n if (contentFormat !== \"headers\") {\n textOutputParts.push(\"\", \"--- Body ---\", text || html || \"(No content)\");\n }\n\n const textOutput = textOutputParts.filter(Boolean).join(\"\\n\");\n const { content: truncatedContent, truncated } = truncateResponse(textOutput);\n\n log(\"Read email\", { messageId, contentFormat, truncated });\n\n // Build response body based on contentFormat\n const responseBody =\n contentFormat === \"headers\" ? undefined : contentFormat === \"text\" ? { text } : { text, html };\n\n return structuredResponse(truncatedContent, {\n id: message.id,\n threadId: message.threadId,\n labelIds: message.labelIds,\n snippet: message.snippet,\n headers,\n body: responseBody,\n attachments,\n internalDate: message.internalDate,\n sizeEstimate: message.sizeEstimate,\n truncated,\n });\n}\n\nexport async function handleSearchEmails(\n gmail: gmail_v1.Gmail,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(SearchEmailsSchema, args);\n if (!validation.success) return validation.response;\n const { query, maxResults, pageToken, labelIds, includeSpamTrash } = validation.data;\n\n const response = await gmail.users.messages.list({\n userId: \"me\",\n q: query,\n maxResults,\n pageToken,\n labelIds,\n includeSpamTrash,\n });\n\n const messages = response.data.messages || [];\n\n if (messages.length === 0) {\n return structuredResponse(`No emails found matching: ${query}`, {\n messages: [],\n nextPageToken: null,\n resultSizeEstimate: 0,\n });\n }\n\n // Fetch basic metadata for each message\n const messageDetails = await Promise.all(\n messages.slice(0, 50).map(async (msg) => {\n const detail = await gmail.users.messages.get({\n userId: \"me\",\n id: msg.id!,\n format: \"metadata\",\n metadataHeaders: [\"From\", \"To\", \"Subject\", \"Date\"],\n });\n const headers = parseEmailHeaders(detail.data.payload?.headers || []);\n return {\n id: detail.data.id,\n threadId: detail.data.threadId,\n snippet: detail.data.snippet,\n from: headers.from,\n to: headers.to,\n subject: headers.subject,\n date: headers.date,\n labelIds: detail.data.labelIds,\n };\n }),\n );\n\n const formattedList = messageDetails\n .map((m) => `- [${m.id}] ${m.subject || \"(No subject)\"} from ${m.from || \"Unknown\"}`)\n .join(\"\\n\");\n\n let textResponse = `Found ${response.data.resultSizeEstimate} email(s):\\n\\n${formattedList}`;\n if (response.data.nextPageToken) {\n textResponse += `\\n\\nMore results available. Use pageToken: ${response.data.nextPageToken}`;\n }\n\n log(\"Searched emails\", { query, count: messages.length });\n\n return structuredResponse(textResponse, {\n messages: messageDetails,\n nextPageToken: response.data.nextPageToken || null,\n resultSizeEstimate: response.data.resultSizeEstimate,\n });\n}\n\nexport async function handleDeleteEmail(\n gmail: gmail_v1.Gmail,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(DeleteEmailSchema, args);\n if (!validation.success) return validation.response;\n const { messageId } = validation.data;\n\n // Normalize to array for uniform handling\n const messageIds = Array.isArray(messageId) ? messageId : [messageId];\n\n if (messageIds.length === 1) {\n // Single delete\n await gmail.users.messages.delete({\n userId: \"me\",\n id: messageIds[0],\n });\n log(\"Deleted email\", { messageId: messageIds[0] });\n return successResponse(`Email ${messageIds[0]} permanently deleted.`);\n }\n\n // Batch delete\n try {\n await gmail.users.messages.batchDelete({\n userId: \"me\",\n requestBody: { ids: messageIds },\n });\n } catch {\n // Batch API may not be available, fall back to individual deletes\n const results = await Promise.allSettled(\n messageIds.map((id) =>\n gmail.users.messages.delete({\n userId: \"me\",\n id,\n }),\n ),\n );\n\n const succeeded = results.filter((r) => r.status === \"fulfilled\").length;\n const failed = results.filter((r) => r.status === \"rejected\").length;\n\n if (failed > 0) {\n return structuredResponse(`Partially completed: ${succeeded} deleted, ${failed} failed.`, {\n succeeded,\n failed,\n total: messageIds.length,\n });\n }\n }\n\n log(\"Deleted emails (batch)\", { count: messageIds.length });\n return successResponse(`Successfully deleted ${messageIds.length} email(s).`);\n}\n\nexport async function handleModifyEmail(\n gmail: gmail_v1.Gmail,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(ModifyEmailSchema, args);\n if (!validation.success) return validation.response;\n const { messageId, addLabelIds, removeLabelIds } = validation.data;\n\n // Normalize to array for uniform handling\n const messageIds = Array.isArray(messageId) ? messageId : [messageId];\n\n if (messageIds.length === 1) {\n // Single modify\n const response = await gmail.users.messages.modify({\n userId: \"me\",\n id: messageIds[0],\n requestBody: { addLabelIds, removeLabelIds },\n });\n\n log(\"Modified email labels\", { messageId: messageIds[0], addLabelIds, removeLabelIds });\n\n return structuredResponse(\n `Email ${messageIds[0]} labels updated.\\nCurrent labels: ${response.data.labelIds?.join(\", \") || \"None\"}`,\n {\n id: response.data.id,\n threadId: response.data.threadId,\n labelIds: response.data.labelIds,\n },\n );\n }\n\n // Batch modify\n await gmail.users.messages.batchModify({\n userId: \"me\",\n requestBody: {\n ids: messageIds,\n addLabelIds,\n removeLabelIds,\n },\n });\n\n log(\"Batch modified emails\", { count: messageIds.length, addLabelIds, removeLabelIds });\n\n return successResponse(\n `Successfully modified labels for ${messageIds.length} email(s).` +\n (addLabelIds ? `\\nAdded labels: ${addLabelIds.join(\", \")}` : \"\") +\n (removeLabelIds ? `\\nRemoved labels: ${removeLabelIds.join(\", \")}` : \"\"),\n );\n}\n\nexport async function handleDownloadAttachment(\n gmail: gmail_v1.Gmail,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(DownloadAttachmentSchema, args);\n if (!validation.success) return validation.response;\n const { messageId, attachmentId, filename, outputPath } = validation.data;\n\n // Get the attachment\n const response = await gmail.users.messages.attachments.get({\n userId: \"me\",\n messageId,\n id: attachmentId,\n });\n\n if (!response.data.data) {\n return errorResponse(\"Attachment data not found\", { code: \"NOT_FOUND\" });\n }\n\n // Decode base64url data\n const data = Buffer.from(response.data.data.replace(/-/g, \"+\").replace(/_/g, \"/\"), \"base64\");\n\n // Determine output filename\n const outputFilename = filename || `attachment_${attachmentId}`;\n const outputDir = outputPath || process.cwd();\n const fullPath = path.join(outputDir, outputFilename);\n\n // Write to file\n await fs.writeFile(fullPath, data);\n\n log(\"Downloaded attachment\", { messageId, attachmentId, path: fullPath });\n\n return structuredResponse(\n `Attachment downloaded successfully.\\nSaved to: ${fullPath}\\nSize: ${data.length} bytes`,\n {\n path: fullPath,\n size: data.length,\n messageId,\n attachmentId,\n },\n );\n}\n\n// ============================================================================\n// Label Management\n// ============================================================================\n\nexport async function handleCreateLabel(\n gmail: gmail_v1.Gmail,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(CreateLabelSchema, args);\n if (!validation.success) return validation.response;\n const { name, messageListVisibility, labelListVisibility, backgroundColor, textColor } =\n validation.data;\n\n const response = await gmail.users.labels.create({\n userId: \"me\",\n requestBody: {\n name,\n messageListVisibility,\n labelListVisibility,\n color:\n backgroundColor || textColor\n ? {\n backgroundColor,\n textColor,\n }\n : undefined,\n },\n });\n\n log(\"Created label\", { labelId: response.data.id, name });\n\n return structuredResponse(`Label \"${name}\" created successfully.\\nID: ${response.data.id}`, {\n id: response.data.id,\n name: response.data.name,\n type: response.data.type,\n messageListVisibility: response.data.messageListVisibility,\n labelListVisibility: response.data.labelListVisibility,\n color: response.data.color,\n });\n}\n\nexport async function handleUpdateLabel(\n gmail: gmail_v1.Gmail,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(UpdateLabelSchema, args);\n if (!validation.success) return validation.response;\n const { labelId, name, messageListVisibility, labelListVisibility, backgroundColor, textColor } =\n validation.data;\n\n const response = await gmail.users.labels.patch({\n userId: \"me\",\n id: labelId,\n requestBody: {\n name,\n messageListVisibility,\n labelListVisibility,\n color:\n backgroundColor || textColor\n ? {\n backgroundColor,\n textColor,\n }\n : undefined,\n },\n });\n\n log(\"Updated label\", { labelId, name });\n\n return structuredResponse(`Label updated successfully.`, {\n id: response.data.id,\n name: response.data.name,\n type: response.data.type,\n messageListVisibility: response.data.messageListVisibility,\n labelListVisibility: response.data.labelListVisibility,\n color: response.data.color,\n });\n}\n\nexport async function handleDeleteLabel(\n gmail: gmail_v1.Gmail,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(DeleteLabelSchema, args);\n if (!validation.success) return validation.response;\n const { labelId } = validation.data;\n\n // Prevent deletion of system labels\n if (SYSTEM_LABELS.has(labelId)) {\n return errorResponse(`Cannot delete system label: ${labelId}`, { code: \"INVALID_INPUT\" });\n }\n\n await gmail.users.labels.delete({\n userId: \"me\",\n id: labelId,\n });\n\n log(\"Deleted label\", { labelId });\n\n return successResponse(`Label ${labelId} deleted successfully.`);\n}\n\nexport async function handleListLabels(\n gmail: gmail_v1.Gmail,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(ListLabelsSchema, args);\n if (!validation.success) return validation.response;\n const { includeSystemLabels } = validation.data;\n\n const response = await gmail.users.labels.list({\n userId: \"me\",\n });\n\n let labels = response.data.labels || [];\n\n // Separate system and user labels\n const systemLabels = labels.filter((l) => l.type === \"system\");\n const userLabels = labels.filter((l) => l.type === \"user\");\n\n if (!includeSystemLabels) {\n labels = userLabels;\n }\n\n const formattedLabels = labels.map((l) => `- ${l.name} [${l.id}] (${l.type})`).join(\"\\n\");\n\n log(\"Listed labels\", {\n total: labels.length,\n system: systemLabels.length,\n user: userLabels.length,\n });\n\n return structuredResponse(`Found ${labels.length} label(s):\\n\\n${formattedLabels}`, {\n labels: labels.map((l) => ({\n id: l.id,\n name: l.name,\n type: l.type,\n messageListVisibility: l.messageListVisibility,\n labelListVisibility: l.labelListVisibility,\n color: l.color,\n messagesTotal: l.messagesTotal,\n messagesUnread: l.messagesUnread,\n })),\n systemLabelCount: systemLabels.length,\n userLabelCount: userLabels.length,\n });\n}\n\nexport async function handleGetOrCreateLabel(\n gmail: gmail_v1.Gmail,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(GetOrCreateLabelSchema, args);\n if (!validation.success) return validation.response;\n const { name, messageListVisibility, labelListVisibility, backgroundColor, textColor } =\n validation.data;\n\n // First try to find existing label\n const listResponse = await gmail.users.labels.list({\n userId: \"me\",\n });\n\n const existingLabel = listResponse.data.labels?.find(\n (l) => l.name?.toLowerCase() === name.toLowerCase(),\n );\n\n if (existingLabel) {\n return structuredResponse(`Label \"${name}\" already exists.\\nID: ${existingLabel.id}`, {\n id: existingLabel.id,\n name: existingLabel.name,\n type: existingLabel.type,\n created: false,\n });\n }\n\n // Create new label\n const createResponse = await gmail.users.labels.create({\n userId: \"me\",\n requestBody: {\n name,\n messageListVisibility,\n labelListVisibility,\n color:\n backgroundColor || textColor\n ? {\n backgroundColor,\n textColor,\n }\n : undefined,\n },\n });\n\n log(\"Created label (get_or_create)\", { labelId: createResponse.data.id, name });\n\n return structuredResponse(\n `Label \"${name}\" created successfully.\\nID: ${createResponse.data.id}`,\n {\n id: createResponse.data.id,\n name: createResponse.data.name,\n type: createResponse.data.type,\n created: true,\n },\n );\n}\n\n// ============================================================================\n// Filter Management\n// ============================================================================\n\n// Helper to build filter criteria from template\nfunction buildFilterFromTemplate(data: {\n template: string;\n labelIds: string[];\n archive?: boolean;\n email?: string;\n subject?: string;\n sizeBytes?: number;\n listAddress?: string;\n}): { criteria: gmail_v1.Schema$FilterCriteria; action: gmail_v1.Schema$FilterAction } {\n const action: gmail_v1.Schema$FilterAction = {\n addLabelIds: data.labelIds,\n removeLabelIds: data.archive ? [\"INBOX\"] : undefined,\n };\n\n let criteria: gmail_v1.Schema$FilterCriteria;\n\n switch (data.template) {\n case \"fromSender\":\n criteria = { from: data.email };\n break;\n case \"withSubject\":\n criteria = { subject: data.subject };\n break;\n case \"withAttachments\":\n criteria = { hasAttachment: true };\n break;\n case \"largeEmails\":\n criteria = { size: data.sizeBytes, sizeComparison: \"larger\" };\n break;\n case \"mailingList\":\n criteria = { query: `list:${data.listAddress || data.email}` };\n break;\n default:\n criteria = {};\n }\n\n return { criteria, action };\n}\n\nexport async function handleCreateFilter(\n gmail: gmail_v1.Gmail,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(CreateFilterSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n let filterCriteria: gmail_v1.Schema$FilterCriteria;\n let filterAction: gmail_v1.Schema$FilterAction;\n\n if (data.template) {\n // Template mode\n const built = buildFilterFromTemplate({\n template: data.template,\n labelIds: data.labelIds!,\n archive: data.archive,\n email: data.email,\n subject: data.subject,\n sizeBytes: data.sizeBytes,\n listAddress: data.listAddress,\n });\n filterCriteria = built.criteria;\n filterAction = built.action;\n } else {\n // Direct mode\n const criteria = data.criteria!;\n const action = data.action!;\n filterCriteria = {\n from: criteria.from,\n to: criteria.to,\n subject: criteria.subject,\n query: criteria.query,\n hasAttachment: criteria.hasAttachment,\n excludeChats: criteria.excludeChats,\n size: criteria.size,\n sizeComparison: criteria.sizeComparison,\n };\n filterAction = {\n addLabelIds: action.addLabelIds,\n removeLabelIds: action.removeLabelIds,\n forward: action.forward,\n };\n }\n\n const response = await gmail.users.settings.filters.create({\n userId: \"me\",\n requestBody: {\n criteria: filterCriteria,\n action: filterAction,\n },\n });\n\n log(\"Created filter\", { filterId: response.data.id, template: data.template });\n\n return structuredResponse(\n `Filter created successfully.${data.template ? ` (template: ${data.template})` : \"\"}\\nID: ${response.data.id}`,\n {\n id: response.data.id,\n template: data.template,\n criteria: response.data.criteria,\n action: response.data.action,\n },\n );\n}\n\nexport async function handleListFilters(\n gmail: gmail_v1.Gmail,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(ListFiltersSchema, args);\n if (!validation.success) return validation.response;\n const { filterId } = validation.data;\n\n // If filterId provided, get that specific filter\n if (filterId) {\n const response = await gmail.users.settings.filters.get({\n userId: \"me\",\n id: filterId,\n });\n\n const filter = response.data;\n const criteriaStr = [\n filter.criteria?.from ? `From: ${filter.criteria.from}` : null,\n filter.criteria?.to ? `To: ${filter.criteria.to}` : null,\n filter.criteria?.subject ? `Subject: ${filter.criteria.subject}` : null,\n filter.criteria?.query ? `Query: ${filter.criteria.query}` : null,\n filter.criteria?.hasAttachment ? \"Has attachment\" : null,\n ]\n .filter(Boolean)\n .join(\"\\n\");\n\n const actionStr = [\n filter.action?.addLabelIds ? `Add labels: ${filter.action.addLabelIds.join(\", \")}` : null,\n filter.action?.removeLabelIds\n ? `Remove labels: ${filter.action.removeLabelIds.join(\", \")}`\n : null,\n filter.action?.forward ? `Forward to: ${filter.action.forward}` : null,\n ]\n .filter(Boolean)\n .join(\"\\n\");\n\n log(\"Retrieved filter\", { filterId });\n\n return structuredResponse(\n `Filter: ${filterId}\\n\\nCriteria:\\n${criteriaStr || \"None\"}\\n\\nActions:\\n${actionStr || \"None\"}`,\n {\n id: filter.id,\n criteria: filter.criteria,\n action: filter.action,\n },\n );\n }\n\n // List all filters\n const response = await gmail.users.settings.filters.list({\n userId: \"me\",\n });\n\n const filters = response.data.filter || [];\n\n if (filters.length === 0) {\n return structuredResponse(\"No filters found.\", { filters: [] });\n }\n\n const formattedFilters = filters\n .map((f) => {\n const criteria = f.criteria || {};\n const criteriaStr = [\n criteria.from ? `from:${criteria.from}` : null,\n criteria.to ? `to:${criteria.to}` : null,\n criteria.subject ? `subject:${criteria.subject}` : null,\n criteria.query ? `query:${criteria.query}` : null,\n ]\n .filter(Boolean)\n .join(\", \");\n return `- [${f.id}] ${criteriaStr || \"(no criteria)\"}`;\n })\n .join(\"\\n\");\n\n log(\"Listed filters\", { count: filters.length });\n\n return structuredResponse(`Found ${filters.length} filter(s):\\n\\n${formattedFilters}`, {\n filters: filters.map((f) => ({\n id: f.id,\n criteria: f.criteria,\n action: f.action,\n })),\n });\n}\n\nexport async function handleDeleteFilter(\n gmail: gmail_v1.Gmail,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(DeleteFilterSchema, args);\n if (!validation.success) return validation.response;\n const { filterId } = validation.data;\n\n await gmail.users.settings.filters.delete({\n userId: \"me\",\n id: filterId,\n });\n\n log(\"Deleted filter\", { filterId });\n\n return successResponse(`Filter ${filterId} deleted successfully.`);\n}\n", "/**\n * Discovery handlers for tool introspection.\n */\n\nimport {\n SERVICE_TOOL_MAP,\n unifiedTools,\n discoveryTools,\n type ToolDefinition,\n} from \"../tools/definitions.js\";\nimport { isServiceEnabled, areUnifiedToolsEnabled, type ServiceName } from \"../config/index.js\";\nimport { successResponse, structuredResponse, type ToolResponse } from \"../utils/responses.js\";\n\ninterface ListToolsInput {\n service?: string;\n keyword?: string;\n includeSchemas?: boolean;\n}\n\ninterface ToolInfo {\n name: string;\n description: string;\n service: string;\n inputSchema?: unknown;\n outputSchema?: unknown;\n}\n\n/**\n * List available tools with optional filtering by service or keyword.\n */\nexport async function handleListTools(args: unknown): Promise<ToolResponse> {\n const input = args as ListToolsInput;\n const { service, keyword, includeSchemas = false } = input;\n\n const results: ToolInfo[] = [];\n const availableServices: string[] = [];\n\n // Helper to add tools from a service\n const addToolsFromService = (serviceName: string, tools: ToolDefinition[]) => {\n for (const tool of tools) {\n // Filter by keyword if provided\n if (keyword) {\n const lowerKeyword = keyword.toLowerCase();\n const matchesName = tool.name.toLowerCase().includes(lowerKeyword);\n const matchesDesc = tool.description.toLowerCase().includes(lowerKeyword);\n if (!matchesName && !matchesDesc) continue;\n }\n\n const toolInfo: ToolInfo = {\n name: tool.name,\n description: tool.description,\n service: serviceName,\n };\n\n if (includeSchemas) {\n toolInfo.inputSchema = tool.inputSchema;\n if (tool.outputSchema) {\n toolInfo.outputSchema = tool.outputSchema;\n }\n }\n\n results.push(toolInfo);\n }\n };\n\n // Add discovery tools (always available)\n if (!service || service === \"discovery\") {\n addToolsFromService(\"discovery\", discoveryTools);\n if (!availableServices.includes(\"discovery\")) {\n availableServices.push(\"discovery\");\n }\n }\n\n // Add tools from each enabled service\n for (const [svcName, serviceTools] of Object.entries(SERVICE_TOOL_MAP)) {\n if (isServiceEnabled(svcName as ServiceName)) {\n if (!availableServices.includes(svcName)) {\n availableServices.push(svcName);\n }\n\n // Filter by service if provided\n if (service && service !== svcName) continue;\n\n addToolsFromService(svcName, serviceTools);\n }\n }\n\n // Add unified tools if enabled\n if (areUnifiedToolsEnabled()) {\n if (!availableServices.includes(\"unified\")) {\n availableServices.push(\"unified\");\n }\n\n if (!service || service === \"unified\") {\n addToolsFromService(\"unified\", unifiedTools);\n }\n }\n\n const data = {\n tools: results,\n totalCount: results.length,\n services: availableServices,\n };\n\n if (results.length === 0) {\n const filterDesc = [\n service ? `service=${service}` : null,\n keyword ? `keyword=\"${keyword}\"` : null,\n ]\n .filter(Boolean)\n .join(\", \");\n return successResponse(`No tools found matching filters: ${filterDesc || \"none\"}`);\n }\n\n const summary = includeSchemas\n ? `Found ${results.length} tool(s) with full schemas`\n : `Found ${results.length} tool(s): ${results.map((t) => t.name).join(\", \")}`;\n\n return structuredResponse(summary, data);\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["authClient", "resolve", "server", "server", "path", "
|
|
3
|
+
"sources": ["../src/utils/logging.ts", "../src/config/services.ts", "../src/utils/responses.ts", "../src/utils/validation.ts", "../src/utils/services.ts", "../src/utils/timeout.ts", "../src/utils/retry.ts", "../src/utils/elicitation.ts", "../src/utils/progress.ts", "../src/utils/pathCache.ts", "../src/utils/mime.ts", "../src/utils/toon.ts", "../src/utils/index.ts", "../src/index.ts", "../src/auth/client.ts", "../src/auth/utils.ts", "../src/auth/server.ts", "../src/auth/tokenManager.ts", "../src/auth.ts", "../src/config/index.ts", "../src/tools/definitions.ts", "../src/prompts/definitions.ts", "../src/handlers/drive.ts", "../src/utils/gdrive-query.ts", "../src/utils/format.ts", "../src/schemas/drive.ts", "../src/schemas/docs.ts", "../src/schemas/sheets.ts", "../src/schemas/slides.ts", "../src/schemas/unified.ts", "../src/schemas/calendar.ts", "../src/schemas/gmail.ts", "../src/handlers/helpers.ts", "../src/utils/mimeTypes.ts", "../src/handlers/docs.ts", "../src/utils/colors.ts", "../src/handlers/sheets.ts", "../src/utils/sheetCache.ts", "../src/handlers/slides.ts", "../src/handlers/unified.ts", "../src/handlers/calendar.ts", "../src/handlers/gmail.ts", "../src/handlers/discovery.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Logging utility for the Google Drive MCP server.\n * Outputs timestamped messages to stderr to avoid interfering with MCP communication.\n */\nexport function log(message: string, data?: unknown): void {\n const timestamp = new Date().toISOString();\n const logMessage = data\n ? `[${timestamp}] ${message}: ${JSON.stringify(data)}`\n : `[${timestamp}] ${message}`;\n console.error(logMessage);\n}\n", "/**\n * Service configuration for enabling/disabling Google Workspace services.\n *\n * Users can set GOOGLE_WORKSPACE_SERVICES env var to a comma-separated list\n * of services to enable (e.g., \"drive,gmail\"). If not set, all services are enabled.\n */\n\nexport const SERVICE_NAMES = [\"drive\", \"docs\", \"sheets\", \"slides\", \"calendar\", \"gmail\"] as const;\nexport type ServiceName = (typeof SERVICE_NAMES)[number];\n\n/** Unified tools require all these services to function */\nconst UNIFIED_REQUIRED_SERVICES: ServiceName[] = [\"drive\", \"docs\", \"sheets\", \"slides\"];\n\n/** Cached set of enabled services (null = not yet parsed) */\nlet enabledServices: Set<ServiceName> | null = null;\n\n/**\n * Parse and return the set of enabled services from GOOGLE_WORKSPACE_SERVICES env var.\n *\n * - Not set \u2192 all services enabled (backward compatible)\n * - Empty \u2192 no services enabled\n * - \"drive,gmail\" \u2192 only those services enabled\n * - Unknown services \u2192 warning logged, valid services still work\n */\nexport function getEnabledServices(): Set<ServiceName> {\n if (enabledServices !== null) return enabledServices;\n\n const envValue = process.env.GOOGLE_WORKSPACE_SERVICES;\n\n // Not set = all enabled (backward compatible)\n if (envValue === undefined) {\n enabledServices = new Set(SERVICE_NAMES);\n return enabledServices;\n }\n\n // Empty = none enabled\n if (envValue.trim() === \"\") {\n enabledServices = new Set();\n return enabledServices;\n }\n\n // Parse comma-separated list\n const requested = envValue\n .split(\",\")\n .map((s) => s.trim().toLowerCase())\n .filter(Boolean);\n const valid = new Set<ServiceName>();\n const unknown: string[] = [];\n\n for (const service of requested) {\n if (SERVICE_NAMES.includes(service as ServiceName)) {\n valid.add(service as ServiceName);\n } else {\n unknown.push(service);\n }\n }\n\n if (unknown.length > 0) {\n console.warn(\n `[google-workspace-mcp] Unknown services: ${unknown.join(\", \")}. ` +\n `Valid: ${SERVICE_NAMES.join(\", \")}`,\n );\n }\n\n enabledServices = valid;\n return enabledServices;\n}\n\n/**\n * Check if a specific service is enabled.\n */\nexport function isServiceEnabled(service: ServiceName): boolean {\n return getEnabledServices().has(service);\n}\n\n/**\n * Check if unified tools (create_file, update_file, get_file_content) are enabled.\n * Unified tools require drive, docs, sheets, and slides to all be enabled.\n */\nexport function areUnifiedToolsEnabled(): boolean {\n const enabled = getEnabledServices();\n return UNIFIED_REQUIRED_SERVICES.every((s) => enabled.has(s));\n}\n\n/**\n * Reset cached service config (for testing).\n */\nexport function resetServiceConfig(): void {\n enabledServices = null;\n}\n\n/**\n * Check if TOON format is enabled for token-efficient responses.\n * Set GOOGLE_WORKSPACE_TOON_FORMAT=true to enable.\n * Default: false (uses JSON for backward compatibility)\n */\nexport function isToonEnabled(): boolean {\n return process.env.GOOGLE_WORKSPACE_TOON_FORMAT === \"true\";\n}\n", "import { isToonEnabled } from \"../config/services.js\";\nimport { log } from \"./logging.js\";\n\n/**\n * Maximum character limit for response content.\n * Large responses can overwhelm agent context windows.\n */\nconst CHARACTER_LIMIT = 25000;\n\nexport interface TruncationResult {\n content: string;\n truncated: boolean;\n originalLength: number;\n}\n\n/**\n * Truncate response content if it exceeds the character limit.\n * Helps prevent overwhelming agent context windows with large API responses.\n */\nexport function truncateResponse(content: string): TruncationResult {\n if (content.length <= CHARACTER_LIMIT) {\n return { content, truncated: false, originalLength: content.length };\n }\n return {\n content:\n content.slice(0, CHARACTER_LIMIT) +\n `\\n\\n[TRUNCATED: Response exceeded ${CHARACTER_LIMIT} characters. ` +\n `Original length: ${content.length}. Consider using more specific queries.]`,\n truncated: true,\n originalLength: content.length,\n };\n}\n\nexport interface ToolResponse {\n content: Array<{ type: string; text: string }>;\n isError: boolean;\n structuredContent?: Record<string, unknown>;\n [x: string]: unknown; // Allow additional properties for MCP SDK compatibility\n}\n\n/**\n * Standard error codes for categorizing errors.\n * Clients can use these to handle specific error types programmatically.\n * Aligned with MCP spec JSON-RPC error codes where applicable.\n */\nexport type ErrorCode =\n | \"NOT_FOUND\" // -30003\n | \"ALREADY_EXISTS\"\n | \"PERMISSION_DENIED\"\n | \"INVALID_INPUT\" // -32602\n | \"RATE_LIMITED\"\n | \"QUOTA_EXCEEDED\" // -30002\n | \"AUTH_REQUIRED\" // -31001\n | \"INVALID_TOKEN\" // -31002\n | \"RESOURCE_LOCKED\" // -30001\n | \"UNSUPPORTED_OPERATION\"\n | \"INTERNAL_ERROR\";\n\nexport interface ErrorOptions {\n /** Standard error code for programmatic handling */\n code?: ErrorCode;\n /** Additional context about the error */\n context?: Record<string, unknown>;\n}\n\n/**\n * Create a success response for a tool call.\n */\nexport function successResponse(text: string): ToolResponse {\n return { content: [{ type: \"text\", text }], isError: false };\n}\n\n/**\n * Create a structured response for a tool call.\n * Includes both human-readable text and machine-parseable structured data.\n * Use this for tools that return structured data (metadata, lists, quotas, etc.).\n */\nexport function structuredResponse(text: string, data: Record<string, unknown>): ToolResponse {\n const response: ToolResponse = {\n content: [{ type: \"text\", text }],\n isError: false,\n };\n\n // Only include structuredContent when TOON is disabled\n // When TOON is enabled, data is already in text - no need to duplicate\n if (!isToonEnabled()) {\n response.structuredContent = data;\n }\n\n return response;\n}\n\n/**\n * Create an error response for a tool call.\n * Logs the error message before returning.\n *\n * @param message - Human-readable error message\n * @param options - Optional error code and context for programmatic handling\n */\nexport function errorResponse(message: string, options?: ErrorOptions): ToolResponse {\n log(\"Error\", { message, ...options });\n\n const response: ToolResponse = {\n content: [{ type: \"text\", text: `Error: ${message}` }],\n isError: true,\n };\n\n if (options?.code || options?.context) {\n response.structuredContent = {\n ...(options.code && { errorCode: options.code }),\n ...(options.context && { context: options.context }),\n };\n }\n\n return response;\n}\n", "import type { z } from \"zod\";\nimport { errorResponse } from \"./responses.js\";\nimport type { ToolResponse } from \"./responses.js\";\n\n/**\n * Result type for validation helper.\n * Either returns validated data or an error response.\n */\nexport type ValidationResult<T> =\n | { success: true; data: T }\n | { success: false; response: ToolResponse };\n\n/**\n * Validates arguments against a Zod schema.\n * Returns a discriminated union to allow clean early returns.\n *\n * @example\n * const validation = validateArgs(MySchema, args);\n * if (!validation.success) return validation.response;\n * const data = validation.data;\n */\nexport function validateArgs<T>(schema: z.ZodSchema<T>, args: unknown): ValidationResult<T> {\n const result = schema.safeParse(args);\n if (!result.success) {\n return {\n success: false,\n response: errorResponse(result.error.issues[0].message),\n };\n }\n return { success: true, data: result.data };\n}\n", "import { google, docs_v1, sheets_v4, slides_v1, calendar_v3, gmail_v1 } from \"googleapis\";\nimport type { OAuth2Client } from \"google-auth-library\";\n\n// Cached service instances\nlet docsService: docs_v1.Docs | null = null;\nlet sheetsService: sheets_v4.Sheets | null = null;\nlet slidesService: slides_v1.Slides | null = null;\nlet calendarService: calendar_v3.Calendar | null = null;\nlet gmailService: gmail_v1.Gmail | null = null;\nlet lastAuthClient: OAuth2Client | null = null;\n\n/**\n * Clear cached services. Should be called when auth changes.\n */\nexport function clearServiceCache(): void {\n docsService = null;\n sheetsService = null;\n slidesService = null;\n calendarService = null;\n gmailService = null;\n lastAuthClient = null;\n}\n\n/**\n * Check if auth client has changed and clear cache if needed.\n */\nfunction checkAuthClient(authClient: OAuth2Client): void {\n if (lastAuthClient !== authClient) {\n clearServiceCache();\n lastAuthClient = authClient;\n }\n}\n\n/**\n * Get or create a cached Google Docs service instance.\n */\nexport function getDocsService(authClient: OAuth2Client): docs_v1.Docs {\n checkAuthClient(authClient);\n if (!docsService) {\n docsService = google.docs({ version: \"v1\", auth: authClient });\n }\n return docsService;\n}\n\n/**\n * Get or create a cached Google Sheets service instance.\n */\nexport function getSheetsService(authClient: OAuth2Client): sheets_v4.Sheets {\n checkAuthClient(authClient);\n if (!sheetsService) {\n sheetsService = google.sheets({ version: \"v4\", auth: authClient });\n }\n return sheetsService;\n}\n\n/**\n * Get or create a cached Google Slides service instance.\n */\nexport function getSlidesService(authClient: OAuth2Client): slides_v1.Slides {\n checkAuthClient(authClient);\n if (!slidesService) {\n slidesService = google.slides({ version: \"v1\", auth: authClient });\n }\n return slidesService;\n}\n\n/**\n * Get or create a cached Google Calendar service instance.\n */\nexport function getCalendarService(authClient: OAuth2Client): calendar_v3.Calendar {\n checkAuthClient(authClient);\n if (!calendarService) {\n calendarService = google.calendar({ version: \"v3\", auth: authClient });\n }\n return calendarService;\n}\n\n/**\n * Get or create a cached Gmail service instance.\n */\nexport function getGmailService(authClient: OAuth2Client): gmail_v1.Gmail {\n checkAuthClient(authClient);\n if (!gmailService) {\n gmailService = google.gmail({ version: \"v1\", auth: authClient });\n }\n return gmailService;\n}\n", "/**\n * Timeout wrapper for async operations.\n * Wraps a promise with a timeout to prevent hanging requests.\n */\n\n/** Default timeout for Google API calls (30 seconds) */\nexport const DEFAULT_API_TIMEOUT_MS = 30000;\n\n/**\n * Wraps a promise with a timeout.\n * If the promise doesn't resolve within the specified time, it rejects with a timeout error.\n *\n * @param promise - The promise to wrap\n * @param ms - Timeout in milliseconds (default: 30000)\n * @param operation - Description of the operation for error messages\n * @returns The result of the promise if it resolves in time\n * @throws Error if the operation times out\n */\nexport async function withTimeout<T>(\n promise: Promise<T>,\n ms: number = DEFAULT_API_TIMEOUT_MS,\n operation: string = \"Operation\",\n): Promise<T> {\n let timeoutId: ReturnType<typeof setTimeout>;\n\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n reject(new Error(`${operation} timed out after ${ms}ms`));\n }, ms);\n });\n\n try {\n const result = await Promise.race([promise, timeoutPromise]);\n clearTimeout(timeoutId!);\n return result;\n } catch (error) {\n clearTimeout(timeoutId!);\n throw error;\n }\n}\n", "/**\n * Retry utility with exponential backoff for Google API rate limiting\n */\n\nimport { log } from \"./logging.js\";\n\nexport interface RetryOptions {\n /** Maximum number of retry attempts (default: 5) */\n maxRetries?: number;\n /** Initial delay in milliseconds (default: 1000) */\n initialDelayMs?: number;\n /** Maximum delay in milliseconds (default: 60000) */\n maxDelayMs?: number;\n /** Multiplier for exponential backoff (default: 2) */\n backoffMultiplier?: number;\n /** Jitter factor to add randomness (0-1, default: 0.1) */\n jitterFactor?: number;\n /** Operation name for logging */\n operationName?: string;\n}\n\nexport interface GoogleApiError {\n code?: number;\n status?: number;\n message?: string;\n errors?: Array<{ reason?: string; domain?: string; message?: string }>;\n}\n\nconst DEFAULT_OPTIONS: Required<RetryOptions> = {\n maxRetries: 5,\n initialDelayMs: 1000,\n maxDelayMs: 60000,\n backoffMultiplier: 2,\n jitterFactor: 0.1,\n operationName: \"API call\",\n};\n\n/**\n * HTTP status codes that indicate a retryable error\n */\nconst RETRYABLE_STATUS_CODES = [\n 429, // Too Many Requests (rate limited)\n 500, // Internal Server Error\n 502, // Bad Gateway\n 503, // Service Unavailable\n 504, // Gateway Timeout\n];\n\n/**\n * Google API error reasons that indicate a retryable error\n */\nconst RETRYABLE_REASONS = [\n \"rateLimitExceeded\",\n \"userRateLimitExceeded\",\n \"quotaExceeded\",\n \"internalError\",\n \"backendError\",\n];\n\n/**\n * Determines if an error is retryable\n */\nfunction isRetryableError(error: unknown): boolean {\n const apiError = error as GoogleApiError;\n\n // Check HTTP status code\n const statusCode = apiError.code || apiError.status;\n if (statusCode && RETRYABLE_STATUS_CODES.includes(statusCode)) {\n return true;\n }\n\n // Check Google API error reasons\n if (apiError.errors?.length) {\n for (const err of apiError.errors) {\n if (err.reason && RETRYABLE_REASONS.includes(err.reason)) {\n return true;\n }\n }\n }\n\n // Check error message for rate limit indicators\n const message = apiError.message?.toLowerCase() || \"\";\n if (\n message.includes(\"rate limit\") ||\n message.includes(\"quota\") ||\n message.includes(\"too many requests\")\n ) {\n return true;\n }\n\n return false;\n}\n\n/**\n * Calculates the delay for the next retry attempt with exponential backoff and jitter\n */\nfunction calculateDelay(attempt: number, options: Required<RetryOptions>): number {\n // Exponential backoff: initialDelay * (multiplier ^ attempt)\n const exponentialDelay = options.initialDelayMs * Math.pow(options.backoffMultiplier, attempt);\n\n // Cap at max delay\n const cappedDelay = Math.min(exponentialDelay, options.maxDelayMs);\n\n // Add jitter to prevent thundering herd\n const jitter = cappedDelay * options.jitterFactor * Math.random();\n const finalDelay = cappedDelay + jitter;\n\n return Math.floor(finalDelay);\n}\n\n/**\n * Sleep for a given number of milliseconds\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Executes an async operation with automatic retry and exponential backoff\n *\n * @param operation - The async operation to execute\n * @param options - Retry configuration options\n * @returns The result of the operation\n * @throws The last error if all retries are exhausted\n *\n * @example\n * ```typescript\n * const result = await withRetry(\n * () => drive.files.list({ pageSize: 100 }),\n * { operationName: 'listFiles', maxRetries: 3 }\n * );\n * ```\n */\nexport async function withRetry<T>(\n operation: () => Promise<T>,\n options: RetryOptions = {},\n): Promise<T> {\n const config = { ...DEFAULT_OPTIONS, ...options };\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= config.maxRetries; attempt++) {\n try {\n return await operation();\n } catch (error) {\n lastError = error;\n\n // Check if we should retry\n if (attempt >= config.maxRetries) {\n log(`${config.operationName} failed after ${config.maxRetries + 1} attempts`, {\n error: error instanceof Error ? error.message : String(error),\n });\n throw error;\n }\n\n if (!isRetryableError(error)) {\n log(`${config.operationName} failed with non-retryable error`, {\n error: error instanceof Error ? error.message : String(error),\n });\n throw error;\n }\n\n // Calculate delay and wait\n const delayMs = calculateDelay(attempt, config);\n log(`${config.operationName} failed, retrying in ${delayMs}ms`, {\n attempt: attempt + 1,\n maxRetries: config.maxRetries,\n error: error instanceof Error ? error.message : String(error),\n });\n\n await sleep(delayMs);\n }\n }\n\n throw lastError;\n}\n\n/**\n * Creates a retry wrapper with preset options\n *\n * @param defaultOptions - Default options for all retry operations\n * @returns A retry function with preset options\n *\n * @example\n * ```typescript\n * const retryWithDefaults = createRetryWrapper({ maxRetries: 3 });\n * const result = await retryWithDefaults(\n * () => drive.files.get({ fileId: '123' }),\n * { operationName: 'getFile' }\n * );\n * ```\n */\nexport function createRetryWrapper(defaultOptions: RetryOptions) {\n return async function <T>(operation: () => Promise<T>, options: RetryOptions = {}): Promise<T> {\n return withRetry(operation, { ...defaultOptions, ...options });\n };\n}\n\n/**\n * Batch operation processor with rate limiting\n *\n * Processes items in parallel with a configurable concurrency limit\n * to avoid overwhelming the Google API.\n *\n * @param items - Items to process\n * @param processor - Function to process each item\n * @param options - Configuration options\n * @returns Results for each item (success or error)\n */\nexport async function withRateLimitedBatch<T, R>(\n items: T[],\n processor: (item: T) => Promise<R>,\n options: {\n /** Maximum concurrent operations (default: 5) */\n concurrency?: number;\n /** Delay between batches in ms (default: 100) */\n batchDelayMs?: number;\n /** Operation name for logging */\n operationName?: string;\n } = {},\n): Promise<Array<{ success: true; result: R } | { success: false; error: string }>> {\n const { concurrency = 5, batchDelayMs = 100, operationName = \"batch operation\" } = options;\n\n const results: Array<{ success: true; result: R } | { success: false; error: string }> = [];\n\n // Process in batches\n for (let i = 0; i < items.length; i += concurrency) {\n const batch = items.slice(i, i + concurrency);\n\n log(`Processing ${operationName} batch`, {\n batchStart: i,\n batchSize: batch.length,\n totalItems: items.length,\n });\n\n const batchResults = await Promise.all(\n batch.map(\n async (item): Promise<{ success: true; result: R } | { success: false; error: string }> => {\n try {\n const result = await withRetry(() => processor(item), {\n operationName,\n maxRetries: 3,\n });\n return { success: true, result };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n },\n ),\n );\n\n results.push(...batchResults);\n\n // Add delay between batches to avoid rate limits\n if (i + concurrency < items.length) {\n await sleep(batchDelayMs);\n }\n }\n\n return results;\n}\n", "/**\n * Elicitation utilities for interactive disambiguation\n *\n * Elicitation allows the server to pause and request additional information\n * from the user during tool execution. This is useful for:\n * - File selection when multiple files match\n * - Confirmation of destructive operations\n * - Requesting missing required parameters\n *\n * When the client doesn't support elicitation, these functions fall back\n * to returning structured responses that prompt the user to retry with\n * more specific parameters.\n */\n\nimport type { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { log } from \"./logging.js\";\n\nexport interface FileOption {\n id: string;\n name: string;\n mimeType?: string;\n modifiedTime?: string;\n path?: string;\n}\n\nexport interface ElicitFileSelectionResult {\n selectedFileId: string | null;\n cancelled: boolean;\n error?: string;\n}\n\nexport interface ElicitConfirmationResult {\n confirmed: boolean;\n cancelled: boolean;\n}\n\n/**\n * Check if the server's connected client supports form elicitation\n */\nexport function supportsFormElicitation(server: Server): boolean {\n // Access the private _clientCapabilities field\n const serverAny = server as unknown as {\n _clientCapabilities?: { elicitation?: { form?: boolean } };\n };\n return !!serverAny._clientCapabilities?.elicitation?.form;\n}\n\n/**\n * Elicit file selection from the user when multiple files match\n *\n * @param server - The MCP server instance\n * @param files - List of matching files to choose from\n * @param message - Optional message to display to the user\n * @returns Selected file ID or null if cancelled/unsupported\n */\nexport async function elicitFileSelection(\n server: Server,\n files: FileOption[],\n message?: string,\n): Promise<ElicitFileSelectionResult> {\n if (files.length === 0) {\n return {\n selectedFileId: null,\n cancelled: false,\n error: \"No files to select from\",\n };\n }\n\n if (files.length === 1) {\n return { selectedFileId: files[0].id, cancelled: false };\n }\n\n // Check if client supports elicitation\n if (!supportsFormElicitation(server)) {\n log(\"Client does not support elicitation, returning file list\");\n return {\n selectedFileId: null,\n cancelled: false,\n error: buildFileSelectionFallbackMessage(files, message),\n };\n }\n\n try {\n // Build enum values from file options\n const enumValues = files.map((f) => f.id);\n\n const result = await server.elicitInput({\n mode: \"form\",\n message: message || \"Multiple files found. Please select one:\",\n requestedSchema: {\n type: \"object\",\n properties: {\n selectedFile: {\n type: \"string\",\n title: \"Select File\",\n description: \"Choose which file to use\",\n enum: enumValues,\n // Note: enumLabels is not standard JSON Schema but some clients may support it\n },\n },\n required: [\"selectedFile\"],\n },\n });\n\n if (result.action === \"accept\" && result.content) {\n const content = result.content as { selectedFile?: string };\n return {\n selectedFileId: content.selectedFile || null,\n cancelled: false,\n };\n }\n\n return { selectedFileId: null, cancelled: true };\n } catch (error) {\n log(\"Elicitation failed\", { error: error instanceof Error ? error.message : String(error) });\n return {\n selectedFileId: null,\n cancelled: false,\n error: buildFileSelectionFallbackMessage(files, message),\n };\n }\n}\n\n/**\n * Elicit confirmation for a potentially destructive operation\n *\n * @param server - The MCP server instance\n * @param message - Description of the operation to confirm\n * @param details - Optional additional details about the operation\n * @returns Whether the user confirmed or cancelled\n */\nexport async function elicitConfirmation(\n server: Server,\n message: string,\n details?: string,\n): Promise<ElicitConfirmationResult> {\n if (!supportsFormElicitation(server)) {\n log(\"Client does not support elicitation for confirmation\");\n return { confirmed: false, cancelled: false };\n }\n\n try {\n const fullMessage = details ? `${message}\\n\\nDetails: ${details}` : message;\n\n const result = await server.elicitInput({\n mode: \"form\",\n message: fullMessage,\n requestedSchema: {\n type: \"object\",\n properties: {\n confirm: {\n type: \"boolean\",\n title: \"Confirm\",\n description: \"Check to confirm this operation\",\n default: false,\n },\n },\n required: [\"confirm\"],\n },\n });\n\n if (result.action === \"accept\" && result.content) {\n const content = result.content as { confirm?: boolean };\n return { confirmed: !!content.confirm, cancelled: false };\n }\n\n return { confirmed: false, cancelled: true };\n } catch (error) {\n log(\"Confirmation elicitation failed\", {\n error: error instanceof Error ? error.message : String(error),\n });\n return { confirmed: false, cancelled: false };\n }\n}\n\n/**\n * Build a fallback message for file selection when elicitation is not available\n */\nfunction buildFileSelectionFallbackMessage(files: FileOption[], message?: string): string {\n const header =\n message ||\n \"Multiple files found with that name. Please specify which one by using the file ID:\";\n\n const fileList = files\n .map((f, i) => {\n let entry = `${i + 1}. \"${f.name}\" (ID: ${f.id})`;\n if (f.mimeType) {\n entry += `\\n Type: ${f.mimeType}`;\n }\n if (f.modifiedTime) {\n entry += `\\n Modified: ${new Date(f.modifiedTime).toLocaleString()}`;\n }\n if (f.path) {\n entry += `\\n Path: ${f.path}`;\n }\n return entry;\n })\n .join(\"\\n\\n\");\n\n return `${header}\\n\\n${fileList}\\n\\nPlease retry with the specific file ID.`;\n}\n\n/**\n * Format disambiguation options for non-elicitation fallback\n */\nexport function formatDisambiguationOptions(\n files: Array<{\n id: string;\n name: string;\n mimeType?: string;\n modifiedTime?: string | null;\n parents?: string[];\n }>,\n contextMessage: string,\n): string {\n const options = files\n .map((f, i) => {\n const modified = f.modifiedTime\n ? ` (modified: ${new Date(f.modifiedTime).toLocaleDateString()})`\n : \"\";\n const type = f.mimeType ? ` [${f.mimeType.split(\".\").pop() || f.mimeType}]` : \"\";\n return `${i + 1}. ${f.name}${type}${modified}\\n ID: ${f.id}`;\n })\n .join(\"\\n\\n\");\n\n return `${contextMessage}\\n\\n${options}\\n\\nTo proceed, please specify the file ID directly.`;\n}\n", "/**\n * Progress notification utilities for long-running operations\n *\n * MCP supports out-of-band progress notifications that allow servers\n * to report progress on long-running operations back to the client.\n *\n * Progress notifications require:\n * 1. The client to include a progressToken in their request\n * 2. The server to send notifications/progress with that token\n */\n\nimport type { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { log } from \"./logging.js\";\n\nexport interface ProgressReporter {\n /**\n * Report progress to the client\n * @param progress - Current progress count\n * @param total - Optional total count (if known)\n * @param message - Optional status message\n */\n report(progress: number, total?: number, message?: string): Promise<void>;\n\n /**\n * Check if progress reporting is available\n */\n isAvailable(): boolean;\n}\n\n/**\n * Create a progress reporter for a given operation\n *\n * @param server - The MCP server instance\n * @param progressToken - The progress token from the client request (if any)\n * @returns A ProgressReporter that can be used to send progress updates\n *\n * @example\n * ```typescript\n * const reporter = createProgressReporter(server, request.params._meta?.progressToken);\n *\n * for (let i = 0; i < items.length; i++) {\n * await processItem(items[i]);\n * await reporter.report(i + 1, items.length, `Processing ${items[i].name}`);\n * }\n * ```\n */\nexport function createProgressReporter(\n server: Server,\n progressToken?: string | number,\n): ProgressReporter {\n // Access the notification method on the server\n // The Server class has a notification method inherited from Protocol\n const serverAny = server as unknown as {\n notification(notification: { method: string; params: unknown }): Promise<void>;\n };\n\n const canReport = !!progressToken;\n\n return {\n isAvailable(): boolean {\n return canReport;\n },\n\n async report(progress: number, total?: number, message?: string): Promise<void> {\n if (!canReport) {\n return;\n }\n\n try {\n await serverAny.notification({\n method: \"notifications/progress\",\n params: {\n progressToken,\n progress,\n ...(total !== undefined && { total }),\n ...(message !== undefined && { message }),\n },\n });\n } catch (error) {\n // Log but don't fail the operation if progress notification fails\n log(\"Failed to send progress notification\", {\n error: error instanceof Error ? error.message : String(error),\n progress,\n total,\n message,\n });\n }\n },\n };\n}\n\n/**\n * Options for batch processing with progress\n */\nexport interface BatchWithProgressOptions<T, R> {\n /** The MCP server instance */\n server: Server;\n /** Progress token from the client request */\n progressToken?: string | number;\n /** Items to process */\n items: T[];\n /** Function to process each item */\n processor: (item: T, index: number) => Promise<R>;\n /** Maximum concurrent operations (default: 5) */\n concurrency?: number;\n /** Operation name for progress messages */\n operationName?: string;\n}\n\n/**\n * Process items in batches with progress reporting\n *\n * @returns Results for each item with success/error status\n *\n * @example\n * ```typescript\n * const results = await processBatchWithProgress({\n * server,\n * progressToken: request.params._meta?.progressToken,\n * items: fileIds,\n * processor: async (fileId) => {\n * await drive.files.trash({ fileId });\n * return { fileId };\n * },\n * operationName: 'Deleting files'\n * });\n * ```\n */\nexport async function processBatchWithProgress<T, R>(\n options: BatchWithProgressOptions<T, R>,\n): Promise<Array<{ success: true; result: R } | { success: false; error: string; item: T }>> {\n const {\n server,\n progressToken,\n items,\n processor,\n concurrency = 5,\n operationName = \"Processing\",\n } = options;\n\n const reporter = createProgressReporter(server, progressToken);\n const results: Array<{ success: true; result: R } | { success: false; error: string; item: T }> =\n [];\n let completed = 0;\n\n // Report initial progress\n if (reporter.isAvailable()) {\n await reporter.report(0, items.length, `Starting ${operationName}...`);\n }\n\n // Process in batches\n for (let i = 0; i < items.length; i += concurrency) {\n const batch = items.slice(i, i + concurrency);\n\n const batchResults = await Promise.all(\n batch.map(\n async (\n item,\n batchIndex,\n ): Promise<{ success: true; result: R } | { success: false; error: string; item: T }> => {\n const index = i + batchIndex;\n try {\n const result = await processor(item, index);\n return { success: true, result };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n item,\n };\n }\n },\n ),\n );\n\n results.push(...batchResults);\n completed += batch.length;\n\n // Report progress after each batch\n if (reporter.isAvailable()) {\n await reporter.report(\n completed,\n items.length,\n `${operationName}: ${completed}/${items.length} complete`,\n );\n }\n }\n\n // Report completion\n if (reporter.isAvailable()) {\n const successCount = results.filter((r) => r.success).length;\n const failCount = results.filter((r) => !r.success).length;\n await reporter.report(\n items.length,\n items.length,\n `${operationName} complete: ${successCount} succeeded, ${failCount} failed`,\n );\n }\n\n return results;\n}\n\n/**\n * Wrap a long-running operation with progress reporting\n *\n * Useful for operations that have intermediate steps you want to report on\n *\n * @example\n * ```typescript\n * const result = await withProgressReporting(\n * server,\n * progressToken,\n * async (report) => {\n * await report(1, 3, 'Step 1: Preparing...');\n * // ... do step 1\n *\n * await report(2, 3, 'Step 2: Processing...');\n * // ... do step 2\n *\n * await report(3, 3, 'Step 3: Finalizing...');\n * // ... do step 3\n *\n * return finalResult;\n * }\n * );\n * ```\n */\nexport async function withProgressReporting<T>(\n server: Server,\n progressToken: string | number | undefined,\n operation: (\n report: (progress: number, total?: number, message?: string) => Promise<void>,\n ) => Promise<T>,\n): Promise<T> {\n const reporter = createProgressReporter(server, progressToken);\n return operation((progress, total, message) => reporter.report(progress, total, message));\n}\n", "/**\n * Simple in-memory cache for path resolution.\n * Caches both full paths and intermediate segment lookups to avoid redundant API calls.\n */\n\ninterface CacheEntry {\n fileId: string;\n timestamp: number;\n}\n\nconst TTL_MS = 60_000; // 60-second cache TTL\n\n// Cache for full paths: \"/foo/bar\" -> fileId\nconst pathCache = new Map<string, CacheEntry>();\n\n// Cache for segment lookups: \"parentId:segmentName\" -> fileId\nconst segmentCache = new Map<string, CacheEntry>();\n\nfunction isExpired(entry: CacheEntry): boolean {\n return Date.now() - entry.timestamp > TTL_MS;\n}\n\n/**\n * Get a cached full path resolution.\n * @param path - The full path (e.g., \"/Documents/Projects\")\n * @returns The cached fileId or undefined if not cached/expired\n */\nexport function getCachedPath(path: string): string | undefined {\n const normalized = normalizePath(path);\n const entry = pathCache.get(normalized);\n if (!entry) return undefined;\n\n if (isExpired(entry)) {\n pathCache.delete(normalized);\n return undefined;\n }\n\n return entry.fileId;\n}\n\n/**\n * Cache a full path resolution.\n * @param path - The full path\n * @param fileId - The resolved file ID\n */\nexport function setCachedPath(path: string, fileId: string): void {\n const normalized = normalizePath(path);\n pathCache.set(normalized, { fileId, timestamp: Date.now() });\n}\n\n/**\n * Get a cached segment lookup.\n * @param parentId - The parent folder ID\n * @param segmentName - The folder/file name to look up\n * @returns The cached fileId or undefined if not cached/expired\n */\nexport function getCachedSegment(parentId: string, segmentName: string): string | undefined {\n const key = `${parentId}:${segmentName}`;\n const entry = segmentCache.get(key);\n if (!entry) return undefined;\n\n if (isExpired(entry)) {\n segmentCache.delete(key);\n return undefined;\n }\n\n return entry.fileId;\n}\n\n/**\n * Cache a segment lookup.\n * @param parentId - The parent folder ID\n * @param segmentName - The folder/file name\n * @param fileId - The resolved file ID\n */\nexport function setCachedSegment(parentId: string, segmentName: string, fileId: string): void {\n const key = `${parentId}:${segmentName}`;\n segmentCache.set(key, { fileId, timestamp: Date.now() });\n}\n\n/**\n * Clear the path cache.\n * @param path - Optional specific path to clear. If not provided, clears all.\n */\nexport function clearPathCache(path?: string): void {\n if (path) {\n const normalized = normalizePath(path);\n pathCache.delete(normalized);\n } else {\n pathCache.clear();\n segmentCache.clear();\n }\n}\n\n/**\n * Get cache statistics for debugging.\n */\nexport function getPathCacheStats(): { pathCount: number; segmentCount: number } {\n return {\n pathCount: pathCache.size,\n segmentCount: segmentCache.size,\n };\n}\n\n/**\n * Clean up expired cache entries.\n * Call periodically to prevent memory leaks in long-running sessions.\n * @returns Number of entries removed\n */\nexport function cleanupExpiredCache(): number {\n let removed = 0;\n const now = Date.now();\n\n for (const [key, entry] of pathCache.entries()) {\n if (now - entry.timestamp > TTL_MS) {\n pathCache.delete(key);\n removed++;\n }\n }\n\n for (const [key, entry] of segmentCache.entries()) {\n if (now - entry.timestamp > TTL_MS) {\n segmentCache.delete(key);\n removed++;\n }\n }\n\n return removed;\n}\n\n/**\n * Normalize a path for consistent caching.\n */\nfunction normalizePath(path: string): string {\n return path.replace(/^\\/+|\\/+$/g, \"\").toLowerCase();\n}\n", "/**\n * MIME message construction utilities for Gmail API.\n * Gmail requires raw email content to be base64url encoded.\n */\n\nexport interface EmailOptions {\n to: string[];\n subject: string;\n body: string;\n html?: string;\n cc?: string[];\n bcc?: string[];\n replyTo?: string;\n attachments?: Array<{\n filename: string;\n content: string; // Base64 encoded\n mimeType?: string;\n }>;\n inReplyTo?: string;\n references?: string;\n}\n\n/**\n * Generate a random boundary for multipart messages\n */\nfunction generateBoundary(): string {\n return `----=_Part_${Date.now()}_${Math.random().toString(36).substring(2)}`;\n}\n\n/**\n * Detect MIME type from filename extension\n */\nfunction detectMimeType(filename: string): string {\n const ext = filename.split(\".\").pop()?.toLowerCase();\n const mimeTypes: Record<string, string> = {\n txt: \"text/plain\",\n html: \"text/html\",\n htm: \"text/html\",\n css: \"text/css\",\n js: \"application/javascript\",\n json: \"application/json\",\n xml: \"application/xml\",\n pdf: \"application/pdf\",\n zip: \"application/zip\",\n gz: \"application/gzip\",\n tar: \"application/x-tar\",\n doc: \"application/msword\",\n docx: \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n xls: \"application/vnd.ms-excel\",\n xlsx: \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n ppt: \"application/vnd.ms-powerpoint\",\n pptx: \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\n png: \"image/png\",\n jpg: \"image/jpeg\",\n jpeg: \"image/jpeg\",\n gif: \"image/gif\",\n svg: \"image/svg+xml\",\n webp: \"image/webp\",\n ico: \"image/x-icon\",\n mp3: \"audio/mpeg\",\n wav: \"audio/wav\",\n mp4: \"video/mp4\",\n webm: \"video/webm\",\n avi: \"video/x-msvideo\",\n mov: \"video/quicktime\",\n csv: \"text/csv\",\n md: \"text/markdown\",\n };\n return mimeTypes[ext || \"\"] || \"application/octet-stream\";\n}\n\n/**\n * Build a MIME message for Gmail API.\n * Returns a base64url-encoded string ready for the Gmail API.\n */\nexport function buildMimeMessage(options: EmailOptions): string {\n const { to, subject, body, html, cc, bcc, replyTo, attachments, inReplyTo, references } = options;\n\n const hasHtml = !!html;\n const hasAttachments = attachments && attachments.length > 0;\n\n // Build headers\n const headers: string[] = [\n `To: ${to.join(\", \")}`,\n `Subject: =?UTF-8?B?${Buffer.from(subject).toString(\"base64\")}?=`,\n \"MIME-Version: 1.0\",\n ];\n\n if (cc && cc.length > 0) {\n headers.push(`Cc: ${cc.join(\", \")}`);\n }\n\n if (bcc && bcc.length > 0) {\n headers.push(`Bcc: ${bcc.join(\", \")}`);\n }\n\n if (replyTo) {\n headers.push(`Reply-To: ${replyTo}`);\n }\n\n if (inReplyTo) {\n headers.push(`In-Reply-To: ${inReplyTo}`);\n }\n\n if (references) {\n headers.push(`References: ${references}`);\n }\n\n let messageBody: string;\n\n if (hasAttachments) {\n // Multipart mixed for attachments\n const mixedBoundary = generateBoundary();\n headers.push(`Content-Type: multipart/mixed; boundary=\"${mixedBoundary}\"`);\n\n const parts: string[] = [];\n\n // Text/HTML part\n if (hasHtml) {\n const altBoundary = generateBoundary();\n parts.push(`--${mixedBoundary}`);\n parts.push(`Content-Type: multipart/alternative; boundary=\"${altBoundary}\"`);\n parts.push(\"\");\n parts.push(`--${altBoundary}`);\n parts.push(\"Content-Type: text/plain; charset=UTF-8\");\n parts.push(\"Content-Transfer-Encoding: base64\");\n parts.push(\"\");\n parts.push(Buffer.from(body).toString(\"base64\"));\n parts.push(`--${altBoundary}`);\n parts.push(\"Content-Type: text/html; charset=UTF-8\");\n parts.push(\"Content-Transfer-Encoding: base64\");\n parts.push(\"\");\n parts.push(Buffer.from(html).toString(\"base64\"));\n parts.push(`--${altBoundary}--`);\n } else {\n parts.push(`--${mixedBoundary}`);\n parts.push(\"Content-Type: text/plain; charset=UTF-8\");\n parts.push(\"Content-Transfer-Encoding: base64\");\n parts.push(\"\");\n parts.push(Buffer.from(body).toString(\"base64\"));\n }\n\n // Attachments\n for (const attachment of attachments!) {\n const mimeType = attachment.mimeType || detectMimeType(attachment.filename);\n parts.push(`--${mixedBoundary}`);\n parts.push(`Content-Type: ${mimeType}; name=\"${attachment.filename}\"`);\n parts.push(\"Content-Transfer-Encoding: base64\");\n parts.push(`Content-Disposition: attachment; filename=\"${attachment.filename}\"`);\n parts.push(\"\");\n parts.push(attachment.content);\n }\n\n parts.push(`--${mixedBoundary}--`);\n messageBody = parts.join(\"\\r\\n\");\n } else if (hasHtml) {\n // Multipart alternative for HTML + plain text\n const altBoundary = generateBoundary();\n headers.push(`Content-Type: multipart/alternative; boundary=\"${altBoundary}\"`);\n\n messageBody = [\n `--${altBoundary}`,\n \"Content-Type: text/plain; charset=UTF-8\",\n \"Content-Transfer-Encoding: base64\",\n \"\",\n Buffer.from(body).toString(\"base64\"),\n `--${altBoundary}`,\n \"Content-Type: text/html; charset=UTF-8\",\n \"Content-Transfer-Encoding: base64\",\n \"\",\n Buffer.from(html).toString(\"base64\"),\n `--${altBoundary}--`,\n ].join(\"\\r\\n\");\n } else {\n // Simple plain text\n headers.push(\"Content-Type: text/plain; charset=UTF-8\");\n headers.push(\"Content-Transfer-Encoding: base64\");\n messageBody = Buffer.from(body).toString(\"base64\");\n }\n\n const fullMessage = headers.join(\"\\r\\n\") + \"\\r\\n\\r\\n\" + messageBody;\n\n // Gmail API requires base64url encoding (not standard base64)\n return Buffer.from(fullMessage)\n .toString(\"base64\")\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/, \"\");\n}\n\n/**\n * Parse email headers from a Gmail message payload\n */\nexport function parseEmailHeaders(\n headers: Array<{ name?: string | null; value?: string | null }>,\n): Record<string, string> {\n const result: Record<string, string> = {};\n for (const header of headers) {\n if (header.name && header.value) {\n result[header.name.toLowerCase()] = header.value;\n }\n }\n return result;\n}\n\n/**\n * Decode base64url-encoded content (as used by Gmail API)\n */\nexport function decodeBase64Url(data: string): string {\n // Convert base64url to standard base64\n const base64 = data.replace(/-/g, \"+\").replace(/_/g, \"/\");\n // Add padding if needed\n const padded = base64 + \"=\".repeat((4 - (base64.length % 4)) % 4);\n return Buffer.from(padded, \"base64\").toString(\"utf-8\");\n}\n", "import { encode } from \"@toon-format/toon\";\nimport { isToonEnabled } from \"../config/services.js\";\n\n/**\n * Encode data as TOON for token-efficient LLM consumption.\n * Returns JSON if TOON is disabled or encoding fails.\n *\n * TOON (Token-Oriented Object Notation) reduces token consumption by 30-60%\n * compared to JSON for uniform arrays by eliminating field name repetition.\n */\nexport function toToon(data: Record<string, unknown>): string {\n if (!isToonEnabled()) {\n return JSON.stringify(data, null, 2);\n }\n try {\n return encode(data);\n } catch {\n return JSON.stringify(data, null, 2);\n }\n}\n", "export { log } from \"./logging.js\";\nexport {\n successResponse,\n structuredResponse,\n errorResponse,\n truncateResponse,\n} from \"./responses.js\";\nexport type { ToolResponse, ErrorCode, ErrorOptions, TruncationResult } from \"./responses.js\";\nexport { validateArgs } from \"./validation.js\";\nexport type { ValidationResult } from \"./validation.js\";\nexport {\n getDocsService,\n getSheetsService,\n getSlidesService,\n getCalendarService,\n getGmailService,\n clearServiceCache,\n} from \"./services.js\";\nexport { withTimeout, DEFAULT_API_TIMEOUT_MS } from \"./timeout.js\";\nexport { withRetry, createRetryWrapper, withRateLimitedBatch } from \"./retry.js\";\nexport type { RetryOptions, GoogleApiError } from \"./retry.js\";\nexport {\n elicitFileSelection,\n elicitConfirmation,\n supportsFormElicitation,\n formatDisambiguationOptions,\n} from \"./elicitation.js\";\nexport type {\n FileOption,\n ElicitFileSelectionResult,\n ElicitConfirmationResult,\n} from \"./elicitation.js\";\nexport {\n createProgressReporter,\n processBatchWithProgress,\n withProgressReporting,\n} from \"./progress.js\";\nexport type { ProgressReporter, BatchWithProgressOptions } from \"./progress.js\";\nexport {\n getCachedPath,\n setCachedPath,\n getCachedSegment,\n setCachedSegment,\n clearPathCache,\n getPathCacheStats,\n cleanupExpiredCache,\n} from \"./pathCache.js\";\nexport { buildMimeMessage, parseEmailHeaders, decodeBase64Url } from \"./mime.js\";\nexport type { EmailOptions } from \"./mime.js\";\nexport { toToon } from \"./toon.js\";\n", "#!/usr/bin/env node\n\nimport { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport {\n CallToolRequestSchema,\n ListResourcesRequestSchema,\n ListToolsRequestSchema,\n ReadResourceRequestSchema,\n ListPromptsRequestSchema,\n GetPromptRequestSchema,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { google } from \"googleapis\";\nimport type { drive_v3 } from \"googleapis\";\nimport { authenticate, AuthServer, initializeOAuth2Client } from \"./auth.js\";\nimport type { OAuth2Client } from \"google-auth-library\";\nimport { fileURLToPath } from \"url\";\nimport { readFileSync } from \"fs\";\nimport { join, dirname } from \"path\";\n\n// Import utilities\nimport {\n log,\n errorResponse,\n getDocsService,\n getSheetsService,\n getSlidesService,\n getCalendarService,\n getGmailService,\n} from \"./utils/index.js\";\n\n// Import service configuration\nimport { isServiceEnabled, areUnifiedToolsEnabled } from \"./config/index.js\";\n\n// Import all tool definitions\nimport { getAllTools } from \"./tools/index.js\";\n\n// Import prompts\nimport { PROMPTS, generatePromptMessages } from \"./prompts/index.js\";\n\n// Import all handlers\nimport {\n // Drive handlers\n handleSearch,\n handleCreateTextFile,\n handleUpdateTextFile,\n handleCreateFolder,\n handleListFolder,\n handleDeleteItem,\n handleRenameItem,\n handleMoveItem,\n handleCopyFile,\n handleGetFileMetadata,\n handleExportFile,\n handleShareFile,\n handleGetSharing,\n handleListRevisions,\n handleRestoreRevision,\n handleDownloadFile,\n handleUploadFile,\n handleGetStorageQuota,\n handleStarFile,\n handleResolveFilePath,\n handleBatchDelete,\n handleBatchRestore,\n handleBatchMove,\n handleBatchShare,\n handleRemovePermission,\n handleListTrash,\n handleRestoreFromTrash,\n handleEmptyTrash,\n handleGetFolderTree,\n // Docs handlers\n handleCreateGoogleDoc,\n handleUpdateGoogleDoc,\n handleGetGoogleDocContent,\n handleAppendToDoc,\n handleInsertTextInDoc,\n handleDeleteTextInDoc,\n handleReplaceTextInDoc,\n handleFormatGoogleDocRange,\n // Sheets handlers\n handleCreateGoogleSheet,\n handleUpdateGoogleSheet,\n handleGetGoogleSheetContent,\n handleFormatGoogleSheetCells,\n handleMergeGoogleSheetCells,\n handleAddGoogleSheetConditionalFormat,\n handleSheetTabs,\n // Slides handlers\n handleCreateGoogleSlides,\n handleUpdateGoogleSlides,\n handleGetGoogleSlidesContent,\n handleCreateGoogleSlidesTextBox,\n handleCreateGoogleSlidesShape,\n handleSlidesSpeakerNotes,\n handleFormatSlidesText,\n handleFormatSlidesShape,\n handleFormatSlideBackground,\n handleListSlidePages,\n // Unified handlers\n handleCreateFile,\n handleUpdateFile,\n handleGetFileContent,\n // Calendar handlers\n handleListCalendars,\n handleListEvents,\n handleGetEvent,\n handleCreateEvent,\n handleUpdateEvent,\n handleDeleteEvent,\n handleFindFreeTime,\n // Gmail handlers\n handleSendEmail,\n handleDraftEmail,\n handleReadEmail,\n handleSearchEmails,\n handleDeleteEmail,\n handleModifyEmail,\n handleDownloadAttachment,\n handleCreateLabel,\n handleUpdateLabel,\n handleDeleteLabel,\n handleListLabels,\n handleGetOrCreateLabel,\n handleCreateFilter,\n handleListFilters,\n handleDeleteFilter,\n // Discovery handlers\n handleListTools,\n} from \"./handlers/index.js\";\nimport type { HandlerContext } from \"./handlers/index.js\";\n\n// -----------------------------------------------------------------------------\n// CONSTANTS & GLOBAL STATE\n// -----------------------------------------------------------------------------\n\n// Drive service - will be created with auth when needed\nlet drive: drive_v3.Drive | null = null;\n\n// Global auth client - will be initialized on first use\nlet authClient: OAuth2Client | null = null;\nlet authenticationPromise: Promise<OAuth2Client> | null = null;\n\n// Get package version\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst packageJsonPath = join(__dirname, \"..\", \"package.json\");\nconst packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\nconst VERSION = packageJson.version;\n\n// -----------------------------------------------------------------------------\n// DRIVE SERVICE HELPER\n// -----------------------------------------------------------------------------\n\nfunction ensureDriveService() {\n if (!authClient) {\n throw new Error(\"Authentication required\");\n }\n\n log(\"About to create drive service\", {\n authClientType: authClient?.constructor?.name,\n hasCredentials: !!authClient.credentials,\n hasAccessToken: !!authClient.credentials?.access_token,\n expiryDate: authClient.credentials?.expiry_date,\n isExpired: authClient.credentials?.expiry_date\n ? Date.now() > authClient.credentials.expiry_date\n : \"no expiry\",\n });\n\n // Create drive service with auth parameter directly\n drive = google.drive({ version: \"v3\", auth: authClient });\n\n log(\"Drive service created/updated\", {\n hasAuth: !!authClient,\n hasCredentials: !!authClient.credentials,\n hasAccessToken: !!authClient.credentials?.access_token,\n });\n}\n\n// Track auth health for debugging\nlet lastAuthError: string | null = null;\n\nasync function verifyAuthHealth(): Promise<boolean> {\n if (!drive) {\n lastAuthError = \"Drive service not initialized\";\n return false;\n }\n\n try {\n const response = await drive.about.get({ fields: \"user\" });\n log(\"Auth verification successful, user:\", response.data.user?.emailAddress);\n lastAuthError = null;\n return true;\n } catch (error: unknown) {\n const err = error as {\n message?: string;\n response?: { status: number; statusText: string };\n };\n lastAuthError = err.message || String(error);\n log(\"WARNING: Auth verification failed:\", lastAuthError);\n if (err.response) {\n log(\"Auth error details:\", {\n status: err.response.status,\n statusText: err.response.statusText,\n });\n }\n return false;\n }\n}\n\n// Export for testing - allows checking last auth error\nexport function getLastAuthError(): string | null {\n return lastAuthError;\n}\n\n// -----------------------------------------------------------------------------\n// SERVER SETUP\n// -----------------------------------------------------------------------------\n\nconst server = new Server(\n {\n name: \"google-workspace-mcp\",\n version: VERSION,\n },\n {\n capabilities: {\n resources: {},\n tools: {\n listChanged: true,\n },\n prompts: {\n listChanged: true,\n },\n },\n },\n);\n\n// -----------------------------------------------------------------------------\n// AUTHENTICATION HELPER\n// -----------------------------------------------------------------------------\n\nasync function ensureAuthenticated() {\n if (!authClient) {\n // If authentication is already in progress, wait for it\n if (authenticationPromise) {\n log(\"Authentication already in progress, waiting...\");\n authClient = await authenticationPromise;\n return;\n }\n\n log(\"Initializing authentication\");\n // Store the promise to prevent concurrent authentication attempts\n authenticationPromise = authenticate();\n\n try {\n authClient = await authenticationPromise;\n log(\"Authentication complete\", {\n authClientType: authClient?.constructor?.name,\n hasCredentials: !!authClient?.credentials,\n hasAccessToken: !!authClient?.credentials?.access_token,\n });\n // Ensure drive service is created with auth\n ensureDriveService();\n\n // Verify auth works by making a test API call (blocking on first auth)\n const healthy = await verifyAuthHealth();\n if (!healthy) {\n log(\"WARNING: Authentication may be broken. Tool calls may fail.\");\n }\n } finally {\n // Clear the promise after completion (success or failure)\n authenticationPromise = null;\n }\n }\n\n // If we already have authClient, ensure drive is up to date\n ensureDriveService();\n}\n\n// -----------------------------------------------------------------------------\n// MCP REQUEST HANDLERS\n// -----------------------------------------------------------------------------\n\nserver.setRequestHandler(ListResourcesRequestSchema, async (request) => {\n await ensureAuthenticated();\n log(\"Handling ListResources request\", { params: request.params });\n const pageSize = 10;\n const params: {\n pageSize: number;\n fields: string;\n pageToken?: string;\n q: string;\n includeItemsFromAllDrives: boolean;\n supportsAllDrives: boolean;\n } = {\n pageSize,\n fields: \"nextPageToken, files(id, name, mimeType)\",\n q: `trashed = false`,\n includeItemsFromAllDrives: true,\n supportsAllDrives: true,\n };\n\n if (request.params?.cursor) {\n params.pageToken = request.params.cursor;\n }\n\n const res = await drive!.files.list(params);\n log(\"Listed files\", { count: res.data.files?.length });\n const files = res.data.files || [];\n\n return {\n resources: files.map((file: drive_v3.Schema$File) => ({\n uri: `gdrive:///${file.id}`,\n mimeType: file.mimeType || \"application/octet-stream\",\n name: file.name || \"Untitled\",\n })),\n nextCursor: res.data.nextPageToken,\n };\n});\n\nserver.setRequestHandler(ReadResourceRequestSchema, async (request) => {\n await ensureAuthenticated();\n log(\"Handling ReadResource request\", { uri: request.params.uri });\n const fileId = request.params.uri.replace(\"gdrive:///\", \"\");\n\n const file = await drive!.files.get({\n fileId,\n fields: \"mimeType\",\n supportsAllDrives: true,\n });\n const mimeType = file.data.mimeType;\n\n if (!mimeType) {\n throw new Error(\"File has no MIME type.\");\n }\n\n if (mimeType.startsWith(\"application/vnd.google-apps\")) {\n // Export logic for Google Docs/Sheets/Slides\n let exportMimeType;\n switch (mimeType) {\n case \"application/vnd.google-apps.document\":\n exportMimeType = \"text/markdown\";\n break;\n case \"application/vnd.google-apps.spreadsheet\":\n exportMimeType = \"text/csv\";\n break;\n case \"application/vnd.google-apps.presentation\":\n exportMimeType = \"text/plain\";\n break;\n case \"application/vnd.google-apps.drawing\":\n exportMimeType = \"image/png\";\n break;\n default:\n exportMimeType = \"text/plain\";\n break;\n }\n\n const res = await drive!.files.export(\n { fileId, mimeType: exportMimeType },\n { responseType: \"text\" },\n );\n\n log(\"Successfully read resource\", { fileId, mimeType });\n return {\n contents: [\n {\n uri: request.params.uri,\n mimeType: exportMimeType,\n text: res.data,\n },\n ],\n };\n } else {\n // Regular file download\n const res = await drive!.files.get(\n { fileId, alt: \"media\", supportsAllDrives: true },\n { responseType: \"arraybuffer\" },\n );\n const contentMime = mimeType || \"application/octet-stream\";\n\n if (contentMime.startsWith(\"text/\") || contentMime === \"application/json\") {\n return {\n contents: [\n {\n uri: request.params.uri,\n mimeType: contentMime,\n text: Buffer.from(res.data as ArrayBuffer).toString(\"utf-8\"),\n },\n ],\n };\n } else {\n return {\n contents: [\n {\n uri: request.params.uri,\n mimeType: contentMime,\n blob: Buffer.from(res.data as ArrayBuffer).toString(\"base64\"),\n },\n ],\n };\n }\n }\n});\n\nserver.setRequestHandler(ListToolsRequestSchema, async () => {\n return { tools: getAllTools() };\n});\n\n// -----------------------------------------------------------------------------\n// PROMPT REQUEST HANDLERS\n// -----------------------------------------------------------------------------\n\nserver.setRequestHandler(ListPromptsRequestSchema, async () => {\n log(\"Handling ListPrompts request\");\n return {\n prompts: PROMPTS.map((prompt) => ({\n name: prompt.name,\n description: prompt.description,\n arguments: prompt.arguments,\n })),\n };\n});\n\nserver.setRequestHandler(GetPromptRequestSchema, async (request) => {\n log(\"Handling GetPrompt request\", { name: request.params.name });\n\n const promptName = request.params.name;\n const promptDef = PROMPTS.find((p) => p.name === promptName);\n\n if (!promptDef) {\n throw new Error(`Unknown prompt: ${promptName}`);\n }\n\n const args = request.params.arguments || {};\n const messages = generatePromptMessages(promptName, args);\n\n return {\n description: promptDef.description,\n messages,\n };\n});\n\n// -----------------------------------------------------------------------------\n// TOOL REGISTRY\n// -----------------------------------------------------------------------------\n\nimport type { ToolResponse } from \"./utils/index.js\";\nimport type { docs_v1, sheets_v4, slides_v1, calendar_v3, gmail_v1 } from \"googleapis\";\n\ninterface ToolServices {\n drive: drive_v3.Drive;\n docs: docs_v1.Docs;\n sheets: sheets_v4.Sheets;\n slides: slides_v1.Slides;\n calendar: calendar_v3.Calendar;\n gmail: gmail_v1.Gmail;\n context: HandlerContext;\n}\n\ntype ToolHandler = (services: ToolServices, args: unknown) => Promise<ToolResponse>;\n\nfunction createToolRegistry(): Record<string, ToolHandler> {\n const registry: Record<string, ToolHandler> = {};\n\n // Discovery tools (always available)\n Object.assign(registry, {\n list_tools: (_services, args) => handleListTools(args),\n } satisfies Record<string, ToolHandler>);\n\n // Drive tools\n if (isServiceEnabled(\"drive\")) {\n Object.assign(registry, {\n search: ({ drive }, args) => handleSearch(drive, args),\n create_text_file: ({ drive }, args) => handleCreateTextFile(drive, args),\n update_text_file: ({ drive }, args) => handleUpdateTextFile(drive, args),\n create_folder: ({ drive }, args) => handleCreateFolder(drive, args),\n list_folder: ({ drive }, args) => handleListFolder(drive, args),\n delete_item: ({ drive }, args) => handleDeleteItem(drive, args),\n rename_item: ({ drive }, args) => handleRenameItem(drive, args),\n move_item: ({ drive }, args) => handleMoveItem(drive, args),\n copy_file: ({ drive }, args) => handleCopyFile(drive, args),\n get_file_metadata: ({ drive }, args) => handleGetFileMetadata(drive, args),\n export_file: ({ drive }, args) => handleExportFile(drive, args),\n share_file: ({ drive }, args) => handleShareFile(drive, args),\n get_sharing: ({ drive }, args) => handleGetSharing(drive, args),\n list_revisions: ({ drive }, args) => handleListRevisions(drive, args),\n restore_revision: ({ drive }, args) => handleRestoreRevision(drive, args),\n download_file: ({ drive }, args) => handleDownloadFile(drive, args),\n upload_file: ({ drive }, args) => handleUploadFile(drive, args),\n get_storage_quota: ({ drive }, args) => handleGetStorageQuota(drive, args),\n star_file: ({ drive }, args) => handleStarFile(drive, args),\n resolve_file_path: ({ drive, context }, args) => handleResolveFilePath(drive, args, context),\n batch_delete: ({ drive, context }, args) => handleBatchDelete(drive, args, context),\n batch_restore: ({ drive, context }, args) => handleBatchRestore(drive, args, context),\n batch_move: ({ drive, context }, args) => handleBatchMove(drive, args, context),\n batch_share: ({ drive, context }, args) => handleBatchShare(drive, args, context),\n remove_permission: ({ drive }, args) => handleRemovePermission(drive, args),\n list_trash: ({ drive }, args) => handleListTrash(drive, args),\n restore_from_trash: ({ drive }, args) => handleRestoreFromTrash(drive, args),\n empty_trash: ({ drive, context }, args) => handleEmptyTrash(drive, args, context),\n get_folder_tree: ({ drive }, args) => handleGetFolderTree(drive, args),\n } satisfies Record<string, ToolHandler>);\n }\n\n // Docs tools\n if (isServiceEnabled(\"docs\")) {\n Object.assign(registry, {\n create_google_doc: ({ drive, docs }, args) => handleCreateGoogleDoc(drive, docs, args),\n update_google_doc: ({ docs }, args) => handleUpdateGoogleDoc(docs, args),\n get_google_doc_content: ({ drive, docs }, args) =>\n handleGetGoogleDocContent(drive, docs, args),\n append_to_doc: ({ docs }, args) => handleAppendToDoc(docs, args),\n insert_text_in_doc: ({ docs }, args) => handleInsertTextInDoc(docs, args),\n delete_text_in_doc: ({ docs }, args) => handleDeleteTextInDoc(docs, args),\n replace_text_in_doc: ({ docs }, args) => handleReplaceTextInDoc(docs, args),\n format_google_doc_range: ({ docs }, args) => handleFormatGoogleDocRange(docs, args),\n } satisfies Record<string, ToolHandler>);\n }\n\n // Sheets tools\n if (isServiceEnabled(\"sheets\")) {\n Object.assign(registry, {\n create_google_sheet: ({ drive, sheets }, args) =>\n handleCreateGoogleSheet(drive, sheets, args),\n update_google_sheet: ({ sheets }, args) => handleUpdateGoogleSheet(sheets, args),\n get_google_sheet_content: ({ drive, sheets }, args) =>\n handleGetGoogleSheetContent(drive, sheets, args),\n format_google_sheet_cells: ({ sheets }, args) => handleFormatGoogleSheetCells(sheets, args),\n merge_google_sheet_cells: ({ sheets }, args) => handleMergeGoogleSheetCells(sheets, args),\n add_google_sheet_conditional_format: ({ sheets }, args) =>\n handleAddGoogleSheetConditionalFormat(sheets, args),\n sheet_tabs: ({ sheets }, args) => handleSheetTabs(sheets, args),\n } satisfies Record<string, ToolHandler>);\n }\n\n // Slides tools\n if (isServiceEnabled(\"slides\")) {\n Object.assign(registry, {\n create_google_slides: ({ drive, slides }, args) =>\n handleCreateGoogleSlides(drive, slides, args),\n update_google_slides: ({ slides }, args) => handleUpdateGoogleSlides(slides, args),\n get_google_slides_content: ({ drive, slides }, args) =>\n handleGetGoogleSlidesContent(drive, slides, args),\n create_google_slides_text_box: ({ slides }, args) =>\n handleCreateGoogleSlidesTextBox(slides, args),\n create_google_slides_shape: ({ slides }, args) => handleCreateGoogleSlidesShape(slides, args),\n slides_speaker_notes: ({ slides }, args) => handleSlidesSpeakerNotes(slides, args),\n format_slides_text: ({ slides }, args) => handleFormatSlidesText(slides, args),\n format_slides_shape: ({ slides }, args) => handleFormatSlidesShape(slides, args),\n format_slide_background: ({ slides }, args) => handleFormatSlideBackground(slides, args),\n list_slide_pages: ({ slides }, args) => handleListSlidePages(slides, args),\n } satisfies Record<string, ToolHandler>);\n }\n\n // Unified smart tools (require drive+docs+sheets+slides)\n if (areUnifiedToolsEnabled()) {\n Object.assign(registry, {\n create_file: ({ drive, docs, sheets, slides }, args) =>\n handleCreateFile(drive, docs, sheets, slides, args),\n update_file: ({ drive, docs, sheets, slides }, args) =>\n handleUpdateFile(drive, docs, sheets, slides, args),\n get_file_content: ({ drive, docs, sheets, slides }, args) =>\n handleGetFileContent(drive, docs, sheets, slides, args),\n } satisfies Record<string, ToolHandler>);\n }\n\n // Calendar tools\n if (isServiceEnabled(\"calendar\")) {\n Object.assign(registry, {\n list_calendars: ({ calendar }, args) => handleListCalendars(calendar, args),\n list_events: ({ calendar }, args) => handleListEvents(calendar, args),\n get_event: ({ calendar }, args) => handleGetEvent(calendar, args),\n create_event: ({ calendar }, args) => handleCreateEvent(calendar, args),\n update_event: ({ calendar }, args) => handleUpdateEvent(calendar, args),\n delete_event: ({ calendar }, args) => handleDeleteEvent(calendar, args),\n find_free_time: ({ calendar }, args) => handleFindFreeTime(calendar, args),\n } satisfies Record<string, ToolHandler>);\n }\n\n // Gmail tools\n if (isServiceEnabled(\"gmail\")) {\n Object.assign(registry, {\n send_email: ({ gmail }, args) => handleSendEmail(gmail, args),\n draft_email: ({ gmail }, args) => handleDraftEmail(gmail, args),\n read_email: ({ gmail }, args) => handleReadEmail(gmail, args),\n search_emails: ({ gmail }, args) => handleSearchEmails(gmail, args),\n delete_email: ({ gmail }, args) => handleDeleteEmail(gmail, args),\n modify_email: ({ gmail }, args) => handleModifyEmail(gmail, args),\n download_attachment: ({ gmail }, args) => handleDownloadAttachment(gmail, args),\n create_label: ({ gmail }, args) => handleCreateLabel(gmail, args),\n update_label: ({ gmail }, args) => handleUpdateLabel(gmail, args),\n delete_label: ({ gmail }, args) => handleDeleteLabel(gmail, args),\n list_labels: ({ gmail }, args) => handleListLabels(gmail, args),\n get_or_create_label: ({ gmail }, args) => handleGetOrCreateLabel(gmail, args),\n create_filter: ({ gmail }, args) => handleCreateFilter(gmail, args),\n list_filters: ({ gmail }, args) => handleListFilters(gmail, args),\n delete_filter: ({ gmail }, args) => handleDeleteFilter(gmail, args),\n } satisfies Record<string, ToolHandler>);\n }\n\n return registry;\n}\n\nconst toolRegistry = createToolRegistry();\n\n// -----------------------------------------------------------------------------\n// TOOL CALL REQUEST HANDLER\n// -----------------------------------------------------------------------------\n\nserver.setRequestHandler(CallToolRequestSchema, async (request) => {\n await ensureAuthenticated();\n log(\"Handling tool request\", { tool: request.params.name });\n\n try {\n const args = request.params.arguments;\n const meta = (request.params as { _meta?: { progressToken?: string | number } })._meta;\n\n const services: ToolServices = {\n drive: drive!,\n docs: getDocsService(authClient!),\n sheets: getSheetsService(authClient!),\n slides: getSlidesService(authClient!),\n calendar: getCalendarService(authClient!),\n gmail: getGmailService(authClient!),\n context: { server, progressToken: meta?.progressToken },\n };\n\n const handler = toolRegistry[request.params.name];\n if (!handler) {\n return errorResponse(`Unknown tool: ${request.params.name}`);\n }\n\n return handler(services, args);\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n log(\"Tool error\", { error: message });\n return errorResponse(message);\n }\n});\n\n// -----------------------------------------------------------------------------\n// CLI HELPER FUNCTIONS\n// -----------------------------------------------------------------------------\n\nfunction showHelp(): void {\n console.log(`\nGoogle Workspace MCP Server v${VERSION}\n\nUsage:\n npx @dguido/google-workspace-mcp [command] [options]\n\nCommands:\n auth Run the authentication flow\n start Start the MCP server (default)\n version Show version information\n help Show this help message\n\nAuth Options:\n --token-path <path> Save tokens to custom path (e.g., .credentials/tokens.json)\n --credentials-path <path> Use custom OAuth credentials file\n\nExamples:\n npx @dguido/google-workspace-mcp auth\n npx @dguido/google-workspace-mcp auth --token-path .credentials/tokens.json\n npx @dguido/google-workspace-mcp auth \\\\\n --credentials-path .credentials/gcp-oauth.keys.json \\\\\n --token-path .credentials/tokens.json\n npx @dguido/google-workspace-mcp start\n npx @dguido/google-workspace-mcp\n\nEnvironment Variables:\n GOOGLE_DRIVE_OAUTH_CREDENTIALS Path to OAuth credentials file\n GOOGLE_WORKSPACE_MCP_TOKEN_PATH Path to store authentication tokens\n\nMulti-Account Setup:\n For project-level credential storage (useful with multiple Google accounts):\n 1. Create a .credentials directory in your project\n 2. Use CLI flags or env vars to point to project-level paths\n 3. Add .credentials/ to your .gitignore\n`);\n}\n\nfunction showVersion(): void {\n console.log(`Google Workspace MCP Server v${VERSION}`);\n}\n\nasync function runAuthServer(tokenPath?: string, credentialsPath?: string): Promise<void> {\n try {\n // Set env vars from CLI flags (CLI takes precedence over existing env vars)\n if (tokenPath) {\n process.env.GOOGLE_WORKSPACE_MCP_TOKEN_PATH = tokenPath;\n }\n if (credentialsPath) {\n process.env.GOOGLE_DRIVE_OAUTH_CREDENTIALS = credentialsPath;\n }\n\n // Initialize OAuth client\n const oauth2Client = await initializeOAuth2Client();\n\n // Create and start auth server\n const authServer = new AuthServer(oauth2Client);\n await authServer.start();\n\n // Wait for completion\n const checkInterval = setInterval(() => {\n if (authServer.authCompletedSuccessfully) {\n clearInterval(checkInterval);\n process.exit(0);\n }\n }, 1000);\n } catch (error) {\n console.error(\"Authentication failed:\", error);\n process.exit(1);\n }\n}\n\n// -----------------------------------------------------------------------------\n// MAIN EXECUTION\n// -----------------------------------------------------------------------------\n\ninterface CliArgs {\n command: string | undefined;\n tokenPath?: string;\n credentialsPath?: string;\n}\n\nfunction parseCliArgs(): CliArgs {\n const args = process.argv.slice(2);\n let command: string | undefined;\n let tokenPath: string | undefined;\n let credentialsPath: string | undefined;\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n\n // Handle --token-path flag\n if (arg === \"--token-path\" && i + 1 < args.length) {\n tokenPath = args[++i];\n continue;\n }\n\n // Handle --credentials-path flag\n if (arg === \"--credentials-path\" && i + 1 < args.length) {\n credentialsPath = args[++i];\n continue;\n }\n\n // Handle special version/help flags as commands\n if (arg === \"--version\" || arg === \"-v\" || arg === \"--help\" || arg === \"-h\") {\n command = arg;\n continue;\n }\n\n // Check for command (first non-option argument)\n if (!command && !arg.startsWith(\"--\")) {\n command = arg;\n continue;\n }\n }\n\n return { command, tokenPath, credentialsPath };\n}\n\nasync function main() {\n const { command, tokenPath, credentialsPath } = parseCliArgs();\n\n switch (command) {\n case \"auth\":\n await runAuthServer(tokenPath, credentialsPath);\n break;\n case \"start\":\n case undefined:\n try {\n // Start the MCP server\n log(\"Starting Google Workspace MCP server...\");\n const transport = new StdioServerTransport();\n await server.connect(transport);\n log(\"Server started successfully\");\n\n // Set up graceful shutdown\n process.on(\"SIGINT\", async () => {\n await server.close();\n process.exit(0);\n });\n process.on(\"SIGTERM\", async () => {\n await server.close();\n process.exit(0);\n });\n } catch (error) {\n console.error(\"Failed to start server:\", error);\n process.exit(1);\n }\n break;\n case \"version\":\n case \"--version\":\n case \"-v\":\n showVersion();\n break;\n case \"help\":\n case \"--help\":\n case \"-h\":\n showHelp();\n break;\n default:\n console.error(`Unknown command: ${command}`);\n showHelp();\n process.exit(1);\n }\n}\n\n// Export server and main for testing or potential programmatic use\nexport { main, server };\n\n// Run the CLI\nmain().catch((error) => {\n console.error(\"Fatal error:\", error);\n process.exit(1);\n});\n", "import { OAuth2Client } from \"google-auth-library\";\nimport * as fs from \"fs/promises\";\nimport { getKeysFilePath, generateCredentialsErrorMessage, OAuthCredentials } from \"./utils.js\";\n\nasync function loadCredentialsFromFile(): Promise<OAuthCredentials> {\n const keysContent = await fs.readFile(getKeysFilePath(), \"utf-8\");\n const keys = JSON.parse(keysContent);\n\n if (keys.installed) {\n // Standard OAuth credentials file format\n const { client_id, client_secret, redirect_uris } = keys.installed;\n return { client_id, client_secret, redirect_uris };\n } else if (keys.web) {\n // Web application credentials format\n const { client_id, client_secret, redirect_uris } = keys.web;\n return { client_id, client_secret, redirect_uris };\n } else if (keys.client_id) {\n // Direct format (simplified)\n return {\n client_id: keys.client_id,\n client_secret: keys.client_secret,\n redirect_uris: keys.redirect_uris || [\"http://localhost:3000/oauth2callback\"],\n };\n } else {\n throw new Error(\n 'Invalid credentials file format. Expected either \"installed\", \"web\" object or direct client_id field.',\n );\n }\n}\n\nasync function loadCredentialsWithFallback(): Promise<OAuthCredentials> {\n try {\n return await loadCredentialsFromFile();\n } catch (fileError) {\n // Check for legacy client_secret.json\n const legacyPath = process.env.GOOGLE_CLIENT_SECRET_PATH || \"client_secret.json\";\n try {\n const legacyContent = await fs.readFile(legacyPath, \"utf-8\");\n const legacyKeys = JSON.parse(legacyContent);\n console.error(\n \"Warning: Using legacy client_secret.json. Please migrate to gcp-oauth.keys.json\",\n );\n\n if (legacyKeys.installed) {\n return legacyKeys.installed;\n } else if (legacyKeys.web) {\n return legacyKeys.web;\n } else {\n throw new Error(\"Invalid legacy credentials format\");\n }\n } catch {\n // Generate helpful error message\n const errorMessage = generateCredentialsErrorMessage();\n throw new Error(\n `${errorMessage}\\n\\nOriginal error: ${fileError instanceof Error ? fileError.message : fileError}`,\n );\n }\n }\n}\n\nexport async function initializeOAuth2Client(): Promise<OAuth2Client> {\n try {\n const credentials = await loadCredentialsWithFallback();\n\n // Use the first redirect URI as the default for the base client\n return new OAuth2Client({\n clientId: credentials.client_id,\n clientSecret: credentials.client_secret || undefined,\n redirectUri: credentials.redirect_uris?.[0] || \"http://localhost:3000/oauth2callback\",\n });\n } catch (error) {\n throw new Error(`Error loading OAuth keys: ${error instanceof Error ? error.message : error}`);\n }\n}\n\nexport async function loadCredentials(): Promise<{\n client_id: string;\n client_secret?: string;\n}> {\n try {\n const credentials = await loadCredentialsWithFallback();\n\n if (!credentials.client_id) {\n throw new Error(\"Client ID missing in credentials.\");\n }\n return {\n client_id: credentials.client_id,\n client_secret: credentials.client_secret,\n };\n } catch (error) {\n throw new Error(`Error loading credentials: ${error instanceof Error ? error.message : error}`);\n }\n}\n", "import * as path from \"path\";\nimport * as os from \"os\";\n\n// Returns the absolute path for the saved token file.\n// Uses XDG Base Directory spec with fallback to home directory\nexport function getSecureTokenPath(): string {\n // Check for custom token path environment variable first (new name)\n const customTokenPath = process.env.GOOGLE_WORKSPACE_MCP_TOKEN_PATH;\n if (customTokenPath) {\n return path.resolve(customTokenPath);\n }\n\n // Legacy environment variable support\n const legacyTokenPath = process.env.GOOGLE_DRIVE_MCP_TOKEN_PATH;\n if (legacyTokenPath) {\n return path.resolve(legacyTokenPath);\n }\n\n // Use XDG Base Directory spec or fallback to ~/.config\n const configHome = process.env.XDG_CONFIG_HOME || path.join(os.homedir(), \".config\");\n\n const tokenDir = path.join(configHome, \"google-workspace-mcp\");\n return path.join(tokenDir, \"tokens.json\");\n}\n\n// Returns the absolute path for the GCP OAuth keys file with priority:\n// 1. Environment variable GOOGLE_DRIVE_OAUTH_CREDENTIALS (highest priority)\n// 2. Current working directory (works for both local dev and npx)\nexport function getKeysFilePath(): string {\n // Priority 1: Environment variable\n const envCredentialsPath = process.env.GOOGLE_DRIVE_OAUTH_CREDENTIALS;\n if (envCredentialsPath) {\n return path.resolve(envCredentialsPath);\n }\n\n // Priority 2: Current working directory\n // For local dev: user runs from project root, so cwd has the keys\n // For npx: user runs from a directory where they've placed their keys\n return path.join(process.cwd(), \"gcp-oauth.keys.json\");\n}\n\n// Interface for OAuth credentials\nexport interface OAuthCredentials {\n client_id: string;\n client_secret?: string;\n redirect_uris?: string[];\n}\n\n// Generate helpful error message for missing credentials\nexport function generateCredentialsErrorMessage(): string {\n return `\nOAuth credentials not found. Please provide credentials using one of these methods:\n\n1. Environment variable:\n Set GOOGLE_DRIVE_OAUTH_CREDENTIALS to the path of your credentials file:\n export GOOGLE_DRIVE_OAUTH_CREDENTIALS=\"/path/to/gcp-oauth.keys.json\"\n\n2. Default file path:\n Place your gcp-oauth.keys.json file in the package root directory.\n\nToken storage:\n- Tokens are saved to: ${getSecureTokenPath()}\n- To use a custom token location, set GOOGLE_WORKSPACE_MCP_TOKEN_PATH environment variable\n\nTo get OAuth credentials:\n1. Go to the Google Cloud Console (https://console.cloud.google.com/)\n2. Create or select a project\n3. Enable the Google Drive, Docs, Sheets, and Slides APIs\n4. Create OAuth 2.0 credentials (Desktop app type)\n5. Download the credentials file as gcp-oauth.keys.json\n`.trim();\n}\n", "import { OAuth2Client } from \"google-auth-library\";\nimport { TokenManager } from \"./tokenManager.js\";\nimport http from \"http\";\nimport os from \"os\";\nimport path from \"path\";\nimport { URL } from \"url\";\nimport open from \"open\";\nimport { loadCredentials } from \"./client.js\";\nimport { log } from \"../utils/logging.js\";\n\n// OAuth scopes for Google Drive, Docs, Sheets, Slides, Calendar, and Gmail\nconst SCOPES = [\n \"https://www.googleapis.com/auth/drive\",\n \"https://www.googleapis.com/auth/drive.file\",\n \"https://www.googleapis.com/auth/drive.readonly\",\n \"https://www.googleapis.com/auth/documents\",\n \"https://www.googleapis.com/auth/spreadsheets\",\n \"https://www.googleapis.com/auth/presentations\",\n \"https://www.googleapis.com/auth/calendar\",\n \"https://www.googleapis.com/auth/gmail.modify\",\n \"https://mail.google.com/\", // Required for message deletion\n \"https://www.googleapis.com/auth/gmail.settings.basic\",\n];\n\nexport class AuthServer {\n private baseOAuth2Client: OAuth2Client; // Used by TokenManager for validation/refresh\n private flowOAuth2Client: OAuth2Client | null = null; // Used specifically for the auth code flow\n private server: http.Server | null = null;\n private tokenManager: TokenManager;\n private portRange: { start: number; end: number };\n public authCompletedSuccessfully = false; // Flag for standalone script\n\n constructor(oauth2Client: OAuth2Client) {\n this.baseOAuth2Client = oauth2Client;\n this.tokenManager = new TokenManager(oauth2Client);\n this.portRange = { start: 3000, end: 3004 };\n }\n\n private createServer(): http.Server {\n return http.createServer(async (req, res) => {\n const url = new URL(req.url || \"/\", `http://localhost`);\n\n if (url.pathname === \"/\") {\n // Handle root - show auth link\n const clientForUrl = this.flowOAuth2Client || this.baseOAuth2Client;\n const authUrl = clientForUrl.generateAuthUrl({\n access_type: \"offline\",\n scope: SCOPES,\n prompt: \"consent\",\n });\n res.writeHead(200, { \"Content-Type\": \"text/html\" });\n res.end(\n `<h1>Google Drive Authentication</h1><a href=\"${authUrl}\">Authenticate with Google</a>`,\n );\n } else if (url.pathname === \"/oauth2callback\") {\n // Handle OAuth callback\n const code = url.searchParams.get(\"code\");\n if (!code) {\n res.writeHead(400, { \"Content-Type\": \"text/plain\" });\n res.end(\"Authorization code missing\");\n return;\n }\n // IMPORTANT: Use the flowOAuth2Client to exchange the code\n if (!this.flowOAuth2Client) {\n res.writeHead(500, { \"Content-Type\": \"text/plain\" });\n res.end(\"Authentication flow not properly initiated.\");\n return;\n }\n try {\n const { tokens } = await this.flowOAuth2Client.getToken(code);\n // Save tokens using the TokenManager (which uses the base client)\n await this.tokenManager.saveTokens(tokens);\n this.authCompletedSuccessfully = true;\n\n // Get the path where tokens were saved\n const tokenPath = this.tokenManager.getTokenPath();\n\n // Detect if tokens are stored in a project directory (not ~/.config)\n const homeConfig = path.join(os.homedir(), \".config\");\n const isProjectLevel = !tokenPath.startsWith(homeConfig);\n const credentialsDir = path.basename(path.dirname(tokenPath));\n const gitignoreWarning = isProjectLevel\n ? `\n <div class=\"warning\">\n <p><strong>\u26A0\uFE0F Security:</strong> Add your credentials directory to .gitignore:</p>\n <p><code>${credentialsDir}/</code></p>\n </div>`\n : \"\";\n\n // Send a more informative HTML response including the path\n res.writeHead(200, { \"Content-Type\": \"text/html\" });\n res.end(`\n <!DOCTYPE html>\n <html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Authentication Successful</title>\n <style>\n body { font-family: sans-serif; display: flex; justify-content: center; align-items: center; height: 100vh; background-color: #f4f4f4; margin: 0; }\n .container { text-align: center; padding: 2em; background-color: #fff; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); max-width: 500px; }\n h1 { color: #4CAF50; }\n p { color: #333; margin-bottom: 0.5em; }\n code { background-color: #eee; padding: 0.2em 0.4em; border-radius: 3px; font-size: 0.9em; }\n .warning { background-color: #fff3cd; border: 1px solid #ffc107; border-radius: 4px; padding: 1em; margin-top: 1em; }\n .warning p { color: #856404; margin: 0.3em 0; }\n </style>\n </head>\n <body>\n <div class=\"container\">\n <h1>Authentication Successful!</h1>\n <p>Your authentication tokens have been saved successfully to:</p>\n <p><code>${tokenPath}</code></p>${gitignoreWarning}\n <p style=\"margin-top: 1em;\">You can now close this browser window.</p>\n </div>\n </body>\n </html>\n `);\n } catch (error: unknown) {\n this.authCompletedSuccessfully = false;\n const message = error instanceof Error ? error.message : \"Unknown error\";\n // Send an HTML error response\n res.writeHead(500, { \"Content-Type\": \"text/html\" });\n res.end(`\n <!DOCTYPE html>\n <html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Authentication Failed</title>\n <style>\n body { font-family: sans-serif; display: flex; justify-content: center; align-items: center; height: 100vh; background-color: #f4f4f4; margin: 0; }\n .container { text-align: center; padding: 2em; background-color: #fff; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }\n h1 { color: #F44336; }\n p { color: #333; }\n </style>\n </head>\n <body>\n <div class=\"container\">\n <h1>Authentication Failed</h1>\n <p>An error occurred during authentication:</p>\n <p><code>${message}</code></p>\n <p>Please try again or check the server logs.</p>\n </div>\n </body>\n </html>\n `);\n }\n } else {\n res.writeHead(404, { \"Content-Type\": \"text/plain\" });\n res.end(\"Not Found\");\n }\n });\n }\n\n async start(openBrowser = true): Promise<boolean> {\n if (await this.tokenManager.validateTokens()) {\n this.authCompletedSuccessfully = true;\n return true;\n }\n\n // Try to start the server and get the port\n const port = await this.startServerOnAvailablePort();\n if (port === null) {\n this.authCompletedSuccessfully = false;\n return false;\n }\n\n // Successfully started server on `port`. Now create the flow-specific OAuth client.\n try {\n const { client_id, client_secret } = await loadCredentials();\n this.flowOAuth2Client = new OAuth2Client(\n client_id,\n client_secret || undefined,\n `http://localhost:${port}/oauth2callback`,\n );\n } catch (error) {\n // Could not load credentials, cannot proceed with auth flow\n log(\"Failed to load credentials for auth flow:\", error);\n this.authCompletedSuccessfully = false;\n await this.stop(); // Stop the server we just started\n return false;\n }\n\n if (openBrowser) {\n // Generate Auth URL using the newly created flow client\n const authorizeUrl = this.flowOAuth2Client.generateAuthUrl({\n access_type: \"offline\",\n scope: SCOPES,\n prompt: \"consent\",\n });\n\n console.error(\"\\n\uD83D\uDD10 AUTHENTICATION REQUIRED\");\n console.error(\"\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\");\n console.error(\"\\nOpening your browser to authenticate...\");\n console.error(`If the browser doesn't open, visit:\\n${authorizeUrl}\\n`);\n\n await open(authorizeUrl);\n }\n\n return true; // Auth flow initiated\n }\n\n private async startServerOnAvailablePort(): Promise<number | null> {\n for (let port = this.portRange.start; port <= this.portRange.end; port++) {\n try {\n await new Promise<void>((resolve, reject) => {\n // Create a new server instance for this port attempt\n const testServer = this.createServer();\n testServer.listen(port, () => {\n this.server = testServer; // Assign to class property *only* if successful\n console.error(`Authentication server listening on http://localhost:${port}`);\n resolve();\n });\n testServer.on(\"error\", (err: NodeJS.ErrnoException) => {\n if (err.code === \"EADDRINUSE\") {\n // Port is in use, close the test server and reject\n testServer.close(() => reject(err));\n } else {\n // Other error, reject\n reject(err);\n }\n });\n });\n return port; // Port successfully bound\n } catch (error: unknown) {\n // Check if it's EADDRINUSE, otherwise rethrow or handle\n const nodeErr = error as NodeJS.ErrnoException;\n if (nodeErr.code !== \"EADDRINUSE\") {\n // An unexpected error occurred during server start\n log(\"Failed to start auth server:\", error);\n return null;\n }\n // EADDRINUSE occurred, loop continues\n }\n }\n console.error(\n \"No available ports for authentication server (tried ports\",\n this.portRange.start,\n \"-\",\n this.portRange.end,\n \")\",\n );\n return null; // No port found\n }\n\n public getRunningPort(): number | null {\n if (this.server) {\n const address = this.server.address();\n if (typeof address === \"object\" && address !== null) {\n return address.port;\n }\n }\n return null;\n }\n\n async stop(): Promise<void> {\n return new Promise((resolve, reject) => {\n if (this.server) {\n this.server.close((err) => {\n if (err) {\n reject(err);\n } else {\n this.server = null;\n resolve();\n }\n });\n } else {\n resolve();\n }\n });\n }\n}\n", "import { OAuth2Client, Credentials } from \"google-auth-library\";\nimport * as fs from \"fs/promises\";\nimport * as path from \"path\";\nimport { getSecureTokenPath } from \"./utils.js\";\nimport { GaxiosError } from \"gaxios\";\nimport { log } from \"../utils/logging.js\";\n\n/** Type guard for NodeJS errors with a `code` property (e.g., ENOENT, EEXIST) */\nfunction isNodeError(error: unknown): error is NodeJS.ErrnoException {\n return error instanceof Error && \"code\" in error;\n}\n\nexport class TokenManager {\n private oauth2Client: OAuth2Client;\n private tokenPath: string;\n\n constructor(oauth2Client: OAuth2Client) {\n this.oauth2Client = oauth2Client;\n this.tokenPath = getSecureTokenPath();\n this.setupTokenRefresh();\n }\n\n // Method to expose the token path\n public getTokenPath(): string {\n return this.tokenPath;\n }\n\n private async ensureTokenDirectoryExists(): Promise<void> {\n try {\n const dir = path.dirname(this.tokenPath);\n await fs.mkdir(dir, { recursive: true });\n } catch (error: unknown) {\n // Ignore errors if directory already exists, re-throw others\n if (isNodeError(error) && error.code !== \"EEXIST\") {\n log(\"Failed to create token directory:\", error);\n throw error;\n }\n }\n }\n\n private setupTokenRefresh(): void {\n this.oauth2Client.on(\"tokens\", async (newTokens) => {\n try {\n await this.ensureTokenDirectoryExists();\n const currentTokens = JSON.parse(await fs.readFile(this.tokenPath, \"utf-8\"));\n const updatedTokens = {\n ...currentTokens,\n ...newTokens,\n refresh_token: newTokens.refresh_token || currentTokens.refresh_token,\n };\n await fs.writeFile(this.tokenPath, JSON.stringify(updatedTokens, null, 2), {\n mode: 0o600,\n });\n log(\"Tokens updated and saved\");\n } catch (error: unknown) {\n // Handle case where currentTokens might not exist yet\n if (isNodeError(error) && error.code === \"ENOENT\") {\n try {\n await fs.writeFile(this.tokenPath, JSON.stringify(newTokens, null, 2), { mode: 0o600 });\n log(\"New tokens saved\");\n } catch (writeError) {\n log(\"Error saving initial tokens:\", writeError);\n }\n } else {\n log(\"Error saving updated tokens:\", error);\n }\n }\n });\n }\n\n async loadSavedTokens(): Promise<boolean> {\n try {\n await this.ensureTokenDirectoryExists();\n\n // Check if token file exists\n const tokenExists = await fs\n .access(this.tokenPath)\n .then(() => true)\n .catch(() => false);\n\n if (!tokenExists) {\n log(\"No token file found at:\", this.tokenPath);\n return false;\n }\n\n const tokens = JSON.parse(await fs.readFile(this.tokenPath, \"utf-8\"));\n\n if (!tokens || typeof tokens !== \"object\") {\n log(\"Invalid token format in file:\", this.tokenPath);\n return false;\n }\n\n this.oauth2Client.setCredentials(tokens);\n log(\"Tokens loaded successfully\");\n return true;\n } catch (error: unknown) {\n log(\"Error loading tokens:\", error);\n // Attempt to delete potentially corrupted token file\n if (isNodeError(error) && error.code !== \"ENOENT\") {\n try {\n await fs.unlink(this.tokenPath);\n log(\"Removed potentially corrupted token file\");\n } catch {\n /* ignore */\n }\n }\n return false;\n }\n }\n\n async refreshTokensIfNeeded(): Promise<boolean> {\n const expiryDate = this.oauth2Client.credentials.expiry_date;\n const isExpired = expiryDate\n ? Date.now() >= expiryDate - 5 * 60 * 1000 // 5 minute buffer\n : !this.oauth2Client.credentials.access_token; // No token means we need one\n\n if (isExpired && this.oauth2Client.credentials.refresh_token) {\n log(\"Auth token expired or nearing expiry, refreshing...\");\n try {\n const response = await this.oauth2Client.refreshAccessToken();\n const newTokens = response.credentials;\n\n if (!newTokens.access_token) {\n throw new Error(\"Received invalid tokens during refresh\");\n }\n // The 'tokens' event listener should handle saving\n this.oauth2Client.setCredentials(newTokens);\n log(\"Token refreshed successfully\");\n return true;\n } catch (refreshError) {\n if (\n refreshError instanceof GaxiosError &&\n refreshError.response?.data?.error === \"invalid_grant\"\n ) {\n log(\n \"Error refreshing auth token: Invalid grant. Token likely expired or revoked. Please re-authenticate.\",\n );\n // Optionally clear the potentially invalid tokens here\n await this.clearTokens();\n return false; // Indicate failure due to invalid grant\n } else {\n // Handle other refresh errors\n log(\"Error refreshing auth token:\", refreshError);\n return false;\n }\n }\n } else if (\n !this.oauth2Client.credentials.access_token &&\n !this.oauth2Client.credentials.refresh_token\n ) {\n log(\"No access or refresh token available. Please re-authenticate.\");\n return false;\n } else {\n // Token is valid or no refresh token available\n return true;\n }\n }\n\n async validateTokens(): Promise<boolean> {\n if (!this.oauth2Client.credentials || !this.oauth2Client.credentials.access_token) {\n // Try loading first if no credentials set\n if (!(await this.loadSavedTokens())) {\n return false; // No saved tokens to load\n }\n // Check again after loading\n if (!this.oauth2Client.credentials || !this.oauth2Client.credentials.access_token) {\n return false; // Still no token after loading\n }\n }\n return this.refreshTokensIfNeeded();\n }\n\n async saveTokens(tokens: Credentials): Promise<void> {\n try {\n await this.ensureTokenDirectoryExists();\n await fs.writeFile(this.tokenPath, JSON.stringify(tokens, null, 2), {\n mode: 0o600,\n });\n this.oauth2Client.setCredentials(tokens);\n log(\"Tokens saved successfully to:\", this.tokenPath);\n } catch (error: unknown) {\n log(\"Error saving tokens:\", error);\n throw error;\n }\n }\n\n async clearTokens(): Promise<void> {\n try {\n this.oauth2Client.setCredentials({}); // Clear in memory\n await fs.unlink(this.tokenPath);\n log(\"Tokens cleared successfully\");\n } catch (error: unknown) {\n if (isNodeError(error) && error.code === \"ENOENT\") {\n // File already gone, which is fine\n log(\"Token file already deleted\");\n } else {\n log(\"Error clearing tokens:\", error);\n // Don't re-throw, clearing is best-effort\n }\n }\n }\n}\n", "// Main authentication module that re-exports and orchestrates the modular components\nimport type { OAuth2Client } from \"google-auth-library\";\nimport { initializeOAuth2Client } from \"./auth/client.js\";\nimport { AuthServer } from \"./auth/server.js\";\nimport { TokenManager } from \"./auth/tokenManager.js\";\nimport { log } from \"./utils/logging.js\";\n\nexport { TokenManager } from \"./auth/tokenManager.js\";\nexport { initializeOAuth2Client } from \"./auth/client.js\";\nexport { AuthServer } from \"./auth/server.js\";\n\n/**\n * Authenticate and return OAuth2 client\n * This is the main entry point for authentication in the MCP server\n */\nexport async function authenticate(): Promise<OAuth2Client> {\n log(\"Initializing authentication...\");\n\n // Initialize OAuth2 client\n const oauth2Client = await initializeOAuth2Client();\n const tokenManager = new TokenManager(oauth2Client);\n\n // Try to validate existing tokens\n if (await tokenManager.validateTokens()) {\n log(\"Authentication successful - using existing tokens\");\n return oauth2Client;\n }\n\n // No valid tokens, need to authenticate\n log(\"No valid authentication tokens found. Starting authentication flow...\");\n\n const authServer = new AuthServer(oauth2Client);\n const authSuccess = await authServer.start(true);\n\n if (!authSuccess) {\n throw new Error(\"Authentication failed. Please check your credentials and try again.\");\n }\n\n // Wait for authentication to complete\n await new Promise<void>((resolve) => {\n const checkInterval = setInterval(async () => {\n if (authServer.authCompletedSuccessfully) {\n clearInterval(checkInterval);\n await authServer.stop();\n resolve();\n }\n }, 1000);\n });\n\n return oauth2Client;\n}\n", "export {\n SERVICE_NAMES,\n type ServiceName,\n getEnabledServices,\n isServiceEnabled,\n areUnifiedToolsEnabled,\n resetServiceConfig,\n} from \"./services.js\";\n", "/**\n * Tool definitions for the Google Drive MCP server.\n * Each tool definition includes name, description, inputSchema, and optionally outputSchema.\n */\n\n// JSON Schema conditional keywords for machine-parseable requirements\ninterface JsonSchemaConditional {\n if?: { properties: Record<string, unknown> };\n then?: { required: string[] };\n}\n\nexport interface ToolDefinition {\n name: string;\n description: string;\n inputSchema: {\n type: \"object\";\n properties: Record<string, unknown>;\n required?: string[];\n // JSON Schema conditional keywords for action-based requirements\n if?: { properties: Record<string, unknown> };\n then?: { required: string[] };\n allOf?: JsonSchemaConditional[];\n };\n outputSchema?: {\n type: \"object\";\n properties: Record<string, unknown>;\n };\n}\n\n// Drive tools\nexport const driveTools: ToolDefinition[] = [\n {\n name: \"search\",\n description: \"Search files and folders in Drive (max 100 results per page)\",\n inputSchema: {\n type: \"object\",\n properties: {\n query: { type: \"string\", description: \"Search query\" },\n searchType: {\n type: \"string\",\n enum: [\"fulltext\", \"name\", \"name_exact\"],\n description:\n \"Search type: 'fulltext' (default, searches file content), 'name' (filename contains query), 'name_exact' (exact filename match)\",\n },\n pageSize: {\n type: \"number\",\n description: \"(optional, default: 50) Results per page (max 100)\",\n },\n pageToken: {\n type: \"string\",\n description: \"(optional) Token for next page of results\",\n },\n },\n required: [\"query\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n files: {\n type: \"array\",\n description: \"List of matching files\",\n items: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"File ID\" },\n name: { type: \"string\", description: \"File name\" },\n mimeType: { type: \"string\", description: \"MIME type\" },\n modifiedTime: {\n type: \"string\",\n description: \"Last modified timestamp\",\n },\n size: { type: \"string\", description: \"File size in bytes\" },\n },\n },\n },\n nextPageToken: {\n type: \"string\",\n description: \"Token for fetching next page, if more results exist\",\n },\n },\n },\n },\n {\n name: \"create_text_file\",\n description: \"Create a text or markdown file\",\n inputSchema: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"File name (.txt or .md)\" },\n content: { type: \"string\", description: \"File content\" },\n parentFolderId: {\n type: \"string\",\n description: \"Parent folder ID (mutually exclusive with parentPath)\",\n },\n parentPath: {\n type: \"string\",\n description:\n \"Parent folder path like '/Documents/Projects' (creates folders if needed, mutually exclusive with parentFolderId)\",\n },\n },\n required: [\"name\", \"content\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Created file ID\" },\n name: { type: \"string\", description: \"Created file name\" },\n },\n },\n },\n {\n name: \"update_text_file\",\n description: \"Update content of a text or markdown file in Google Drive\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"ID of the file to update\" },\n content: { type: \"string\", description: \"New file content\" },\n name: {\n type: \"string\",\n description: \"Optional new name (.txt or .md)\",\n },\n },\n required: [\"fileId\", \"content\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"Updated file name\" },\n modifiedTime: {\n type: \"string\",\n description: \"Last modified timestamp (ISO 8601)\",\n },\n },\n },\n },\n {\n name: \"create_folder\",\n description: \"Create a new folder in Google Drive\",\n inputSchema: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"Folder name\" },\n parent: {\n type: \"string\",\n description: \"Parent folder ID (mutually exclusive with parentPath)\",\n },\n parentPath: {\n type: \"string\",\n description:\n \"Parent folder path like '/Documents/Projects' (creates folders if needed, mutually exclusive with parent)\",\n },\n },\n required: [\"name\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Created folder ID\" },\n name: { type: \"string\", description: \"Created folder name\" },\n },\n },\n },\n {\n name: \"list_folder\",\n description: \"List folder contents (max 100 items per page)\",\n inputSchema: {\n type: \"object\",\n properties: {\n folderId: { type: \"string\", description: \"(optional) Folder ID (defaults to root)\" },\n pageSize: {\n type: \"number\",\n description: \"(optional, default: 50) Items to return (max 100)\",\n },\n pageToken: { type: \"string\", description: \"(optional) Token for next page\" },\n },\n },\n outputSchema: {\n type: \"object\",\n properties: {\n items: {\n type: \"array\",\n description: \"List of files and folders\",\n items: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Item ID\" },\n name: { type: \"string\", description: \"Item name\" },\n mimeType: { type: \"string\", description: \"MIME type\" },\n modifiedTime: {\n type: \"string\",\n description: \"Last modified timestamp\",\n },\n size: {\n type: \"string\",\n description: \"File size in bytes (folders have no size)\",\n },\n },\n },\n },\n nextPageToken: {\n type: \"string\",\n description: \"Token for fetching next page, if more items exist\",\n },\n },\n },\n },\n {\n name: \"delete_item\",\n description: \"Move items to trash\",\n inputSchema: {\n type: \"object\",\n properties: {\n itemId: { type: \"string\", description: \"ID of the item to delete\" },\n },\n required: [\"itemId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\", description: \"Whether the deletion succeeded\" },\n itemId: { type: \"string\", description: \"ID of the deleted item\" },\n },\n },\n },\n {\n name: \"rename_item\",\n description: \"Rename a file or folder\",\n inputSchema: {\n type: \"object\",\n properties: {\n itemId: { type: \"string\", description: \"ID of the item to rename\" },\n newName: { type: \"string\", description: \"New name\" },\n },\n required: [\"itemId\", \"newName\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\", description: \"Whether the rename succeeded\" },\n id: { type: \"string\", description: \"Item ID\" },\n name: { type: \"string\", description: \"New name\" },\n },\n },\n },\n {\n name: \"move_item\",\n description: \"Move items to a new folder\",\n inputSchema: {\n type: \"object\",\n properties: {\n itemId: { type: \"string\", description: \"ID of the item to move\" },\n destinationFolderId: {\n type: \"string\",\n description: \"Destination folder ID (mutually exclusive with destinationPath)\",\n },\n destinationPath: {\n type: \"string\",\n description:\n \"Destination folder path like '/Archive/2024' (creates folders if needed, mutually exclusive with destinationFolderId)\",\n },\n },\n required: [\"itemId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n itemName: { type: \"string\", description: \"Name of the moved item\" },\n destinationName: {\n type: \"string\",\n description: \"Destination folder name\",\n },\n },\n },\n },\n {\n name: \"copy_file\",\n description: \"Copy a file with optional new name\",\n inputSchema: {\n type: \"object\",\n properties: {\n sourceFileId: { type: \"string\", description: \"ID of the file to copy\" },\n destinationName: {\n type: \"string\",\n description: \"Name for the copied file (defaults to 'Copy of <original>')\",\n },\n destinationFolderId: {\n type: \"string\",\n description: \"Destination folder ID (defaults to same folder as source)\",\n },\n },\n required: [\"sourceFileId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"New file ID\" },\n name: { type: \"string\", description: \"New file name\" },\n webViewLink: {\n type: \"string\",\n description: \"Link to view the new file\",\n },\n },\n },\n },\n {\n name: \"get_file_metadata\",\n description: \"Get file or folder metadata\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"ID of the file or folder\" },\n },\n required: [\"fileId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"File ID\" },\n name: { type: \"string\", description: \"File name\" },\n mimeType: { type: \"string\", description: \"MIME type\" },\n size: { type: \"string\", description: \"File size in bytes\" },\n createdTime: {\n type: \"string\",\n description: \"Creation timestamp (ISO 8601)\",\n },\n modifiedTime: {\n type: \"string\",\n description: \"Last modified timestamp (ISO 8601)\",\n },\n owners: {\n type: \"array\",\n description: \"List of file owners\",\n items: {\n type: \"object\",\n properties: {\n displayName: { type: \"string\" },\n emailAddress: { type: \"string\" },\n },\n },\n },\n shared: { type: \"boolean\", description: \"Whether the file is shared\" },\n starred: {\n type: \"boolean\",\n description: \"Whether the file is starred\",\n },\n description: { type: \"string\", description: \"File description\" },\n webViewLink: {\n type: \"string\",\n description: \"Link to view file in browser\",\n },\n parents: {\n type: \"array\",\n description: \"IDs of parent folders\",\n items: { type: \"string\" },\n },\n },\n },\n },\n {\n name: \"export_file\",\n description: \"Export Workspace files to other formats\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: {\n type: \"string\",\n description: \"ID of the Google Doc, Sheet, or Slides to export\",\n },\n format: {\n type: \"string\",\n description: \"Export format: pdf, docx (Docs), xlsx/csv/tsv (Sheets), pptx (Slides)\",\n enum: [\"pdf\", \"docx\", \"xlsx\", \"pptx\", \"csv\", \"tsv\", \"odt\", \"ods\", \"odp\"],\n },\n outputPath: {\n type: \"string\",\n description: \"Optional directory path to save the file (returns base64 if not provided)\",\n },\n },\n required: [\"fileId\", \"format\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n fileName: { type: \"string\", description: \"Original file name\" },\n format: { type: \"string\", description: \"Export format used\" },\n outputPath: {\n type: \"string\",\n description: \"Path where file was saved (if outputPath provided)\",\n },\n size: { type: \"number\", description: \"File size in bytes\" },\n base64Content: {\n type: \"string\",\n description: \"Base64-encoded content (if no outputPath)\",\n },\n },\n },\n },\n // Sharing tools\n {\n name: \"share_file\",\n description: \"Share a file with a user, group, domain, or make public\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"File ID to share\" },\n role: {\n type: \"string\",\n enum: [\"reader\", \"commenter\", \"writer\", \"organizer\"],\n description: \"Permission role\",\n },\n type: {\n type: \"string\",\n enum: [\"user\", \"group\", \"domain\", \"anyone\"],\n description: \"Permission type\",\n },\n emailAddress: {\n type: \"string\",\n description: \"Email (required for user/group)\",\n },\n domain: {\n type: \"string\",\n description: \"Domain (required for domain type)\",\n },\n sendNotificationEmail: {\n type: \"boolean\",\n description: \"Send notification email (default: true)\",\n },\n emailMessage: {\n type: \"string\",\n description: \"Custom message for notification\",\n },\n },\n required: [\"fileId\", \"role\", \"type\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n fileName: { type: \"string\", description: \"Name of the shared file\" },\n permissionId: { type: \"string\", description: \"Created permission ID\" },\n role: { type: \"string\", description: \"Permission role granted\" },\n target: { type: \"string\", description: \"Who the file was shared with\" },\n },\n },\n },\n {\n name: \"get_sharing\",\n description: \"Get sharing settings and permissions for a file\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"File ID\" },\n },\n required: [\"fileId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n fileName: { type: \"string\", description: \"Name of the file\" },\n webViewLink: {\n type: \"string\",\n description: \"Link to view file in browser\",\n },\n permissions: {\n type: \"array\",\n description: \"List of permissions on the file\",\n items: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Permission ID\" },\n role: {\n type: \"string\",\n description: \"Permission role\",\n enum: [\"owner\", \"organizer\", \"fileOrganizer\", \"writer\", \"commenter\", \"reader\"],\n },\n type: {\n type: \"string\",\n description: \"Permission type\",\n enum: [\"user\", \"group\", \"domain\", \"anyone\"],\n },\n emailAddress: {\n type: \"string\",\n description: \"Email address (for user/group)\",\n },\n domain: {\n type: \"string\",\n description: \"Domain (for domain type)\",\n },\n displayName: {\n type: \"string\",\n description: \"Display name of the user/group\",\n },\n },\n },\n },\n },\n },\n },\n // Revision tools\n {\n name: \"list_revisions\",\n description: \"List file version history\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"File ID\" },\n pageSize: {\n type: \"number\",\n description: \"Max revisions to return (default 100, max 1000)\",\n },\n },\n required: [\"fileId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n fileName: { type: \"string\", description: \"Name of the file\" },\n revisions: {\n type: \"array\",\n description: \"List of file revisions\",\n items: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Revision ID\" },\n modifiedTime: {\n type: \"string\",\n description: \"When revision was created (ISO 8601)\",\n },\n size: {\n type: \"string\",\n description: \"Size of revision in bytes\",\n },\n keepForever: {\n type: \"boolean\",\n description: \"Whether revision is pinned\",\n },\n lastModifyingUser: {\n type: \"object\",\n description: \"User who created this revision\",\n properties: {\n displayName: { type: \"string\" },\n emailAddress: { type: \"string\" },\n },\n },\n },\n },\n },\n },\n },\n },\n {\n name: \"restore_revision\",\n description: \"Restore file to previous revision\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"File ID\" },\n revisionId: { type: \"string\", description: \"Revision ID to restore\" },\n },\n required: [\"fileId\", \"revisionId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n fileName: { type: \"string\", description: \"Name of the restored file\" },\n revisionId: {\n type: \"string\",\n description: \"Revision that was restored\",\n },\n },\n },\n },\n // Binary file tools\n {\n name: \"download_file\",\n description: \"Download a file as base64 or to disk\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"File ID\" },\n outputPath: {\n type: \"string\",\n description: \"Directory to save file (optional, returns base64 if not provided)\",\n },\n },\n required: [\"fileId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n fileName: {\n type: \"string\",\n description: \"Name of the downloaded file\",\n },\n mimeType: { type: \"string\", description: \"MIME type of the file\" },\n size: { type: \"number\", description: \"File size in bytes\" },\n outputPath: {\n type: \"string\",\n description: \"Path where file was saved (if outputPath provided)\",\n },\n base64Content: {\n type: \"string\",\n description: \"Base64-encoded content (if no outputPath)\",\n },\n },\n },\n },\n {\n name: \"upload_file\",\n description: \"Upload file from disk or base64\",\n inputSchema: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"File name with extension\" },\n sourcePath: { type: \"string\", description: \"Path to source file\" },\n base64Content: {\n type: \"string\",\n description: \"Base64-encoded content\",\n },\n mimeType: {\n type: \"string\",\n description: \"MIME type (auto-detected from extension if omitted)\",\n },\n folderId: {\n type: \"string\",\n description: \"Destination folder ID (mutually exclusive with folderPath)\",\n },\n folderPath: {\n type: \"string\",\n description:\n \"Destination folder path like '/Documents/Uploads' (creates folders if needed, mutually exclusive with folderId)\",\n },\n },\n required: [\"name\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Uploaded file ID\" },\n name: { type: \"string\", description: \"Uploaded file name\" },\n webViewLink: { type: \"string\", description: \"Link to view the file\" },\n },\n },\n },\n // Metadata tools\n {\n name: \"get_storage_quota\",\n description: \"Get Google Drive storage quota and usage\",\n inputSchema: {\n type: \"object\",\n properties: {},\n required: [],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n user: {\n type: \"object\",\n description: \"User information\",\n properties: {\n displayName: { type: \"string\" },\n emailAddress: { type: \"string\" },\n },\n },\n storageQuota: {\n type: \"object\",\n description: \"Storage quota details\",\n properties: {\n limit: {\n type: \"string\",\n description: \"Total storage limit in bytes (null if unlimited)\",\n },\n usage: { type: \"string\", description: \"Total bytes used\" },\n usageInDrive: {\n type: \"string\",\n description: \"Bytes used in Drive\",\n },\n usageInDriveTrash: {\n type: \"string\",\n description: \"Bytes used in Drive trash\",\n },\n },\n },\n },\n },\n },\n {\n name: \"star_file\",\n description: \"Star or unstar a file in Google Drive\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"File ID\" },\n starred: {\n type: \"boolean\",\n description: \"true to star, false to unstar\",\n },\n },\n required: [\"fileId\", \"starred\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n success: { type: \"boolean\", description: \"Whether the operation succeeded\" },\n fileId: { type: \"string\", description: \"File ID\" },\n starred: { type: \"boolean\", description: \"Current starred status\" },\n },\n },\n },\n // File path resolution\n {\n name: \"resolve_file_path\",\n description: \"Resolve file path to ID\",\n inputSchema: {\n type: \"object\",\n properties: {\n path: {\n type: \"string\",\n description:\n \"File path to resolve (e.g., 'Documents/Projects/Budget.xlsx' or '/My Folder/report.pdf')\",\n },\n type: {\n type: \"string\",\n description: \"Type of item to find: 'file', 'folder', or 'any' (default)\",\n enum: [\"file\", \"folder\", \"any\"],\n },\n },\n required: [\"path\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"File ID\" },\n name: { type: \"string\", description: \"File name\" },\n path: { type: \"string\", description: \"Full resolved path\" },\n mimeType: { type: \"string\", description: \"MIME type\" },\n modifiedTime: {\n type: \"string\",\n description: \"Last modified timestamp\",\n },\n },\n },\n },\n // Batch operations\n {\n name: \"batch_delete\",\n description: \"Batch move files to trash (max 100 per batch)\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileIds: {\n type: \"array\",\n description: \"Array of file IDs to delete (max 100)\",\n items: { type: \"string\" },\n },\n },\n required: [\"fileIds\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n succeeded: { type: \"number\", description: \"Number of files successfully deleted\" },\n failed: { type: \"number\", description: \"Number of files that failed\" },\n errors: {\n type: \"array\",\n description: \"List of errors for failed operations\",\n items: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\" },\n error: { type: \"string\" },\n },\n },\n },\n },\n },\n },\n {\n name: \"batch_restore\",\n description: \"Batch restore files from trash (max 100 per batch)\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileIds: {\n type: \"array\",\n description: \"Array of file IDs to restore from trash (max 100)\",\n items: { type: \"string\" },\n },\n },\n required: [\"fileIds\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n succeeded: { type: \"number\", description: \"Number of files successfully restored\" },\n failed: { type: \"number\", description: \"Number of files that failed\" },\n errors: {\n type: \"array\",\n description: \"List of errors for failed operations\",\n items: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\" },\n error: { type: \"string\" },\n },\n },\n },\n },\n },\n },\n {\n name: \"batch_move\",\n description: \"Batch move files to folder (max 100 per batch)\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileIds: {\n type: \"array\",\n description: \"Array of file IDs to move (max 100)\",\n items: { type: \"string\" },\n },\n destinationFolderId: {\n type: \"string\",\n description: \"Destination folder ID (mutually exclusive with destinationPath)\",\n },\n destinationPath: {\n type: \"string\",\n description:\n \"Destination folder path like '/Archive/2024' (creates folders if needed, mutually exclusive with destinationFolderId)\",\n },\n },\n required: [\"fileIds\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n succeeded: { type: \"number\", description: \"Number of files successfully moved\" },\n failed: { type: \"number\", description: \"Number of files that failed\" },\n destinationFolder: {\n type: \"object\",\n description: \"Destination folder info\",\n properties: {\n id: { type: \"string\" },\n name: { type: \"string\" },\n },\n },\n errors: {\n type: \"array\",\n description: \"List of errors for failed operations\",\n items: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\" },\n error: { type: \"string\" },\n },\n },\n },\n },\n },\n },\n {\n name: \"batch_share\",\n description: \"Batch share files with a user (max 100 per batch)\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileIds: {\n type: \"array\",\n description: \"Array of file IDs to share (max 100)\",\n items: { type: \"string\" },\n },\n email: { type: \"string\", description: \"Email address to share with\" },\n role: {\n type: \"string\",\n description: \"Permission role\",\n enum: [\"reader\", \"writer\", \"commenter\"],\n },\n sendNotification: {\n type: \"boolean\",\n description: \"(optional, default: true) Send email notification\",\n },\n },\n required: [\"fileIds\", \"email\", \"role\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n succeeded: { type: \"number\", description: \"Number of files successfully shared\" },\n failed: { type: \"number\", description: \"Number of files that failed\" },\n sharedWith: { type: \"string\", description: \"Email address files were shared with\" },\n role: { type: \"string\", description: \"Permission role granted\" },\n errors: {\n type: \"array\",\n description: \"List of errors for failed operations\",\n items: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\" },\n error: { type: \"string\" },\n },\n },\n },\n },\n },\n },\n // Permission management\n {\n name: \"remove_permission\",\n description: \"Remove sharing permission from a file\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"File ID\" },\n permissionId: {\n type: \"string\",\n description: \"Permission ID (from getSharing)\",\n },\n email: {\n type: \"string\",\n description: \"Email address to remove (alternative to permissionId)\",\n },\n },\n required: [\"fileId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n fileName: { type: \"string\", description: \"Name of the file\" },\n removedTarget: {\n type: \"string\",\n description: \"Email or permission ID that was removed\",\n },\n },\n },\n },\n // Trash management\n {\n name: \"list_trash\",\n description: \"List files in trash\",\n inputSchema: {\n type: \"object\",\n properties: {\n pageSize: {\n type: \"number\",\n description: \"Items per page (default 50, max 100)\",\n },\n pageToken: { type: \"string\", description: \"Token for next page\" },\n },\n },\n outputSchema: {\n type: \"object\",\n properties: {\n files: {\n type: \"array\",\n description: \"Files in trash\",\n items: {\n type: \"object\",\n properties: {\n id: { type: \"string\" },\n name: { type: \"string\" },\n mimeType: { type: \"string\" },\n size: { type: \"string\" },\n trashedTime: { type: \"string\" },\n },\n },\n },\n nextPageToken: { type: \"string\", description: \"Token for next page\" },\n },\n },\n },\n {\n name: \"restore_from_trash\",\n description: \"Restore a file from trash\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"File ID to restore\" },\n destinationFolderId: {\n type: \"string\",\n description:\n \"Optional destination folder ID (mutually exclusive with destinationPath). If not provided, restores to original location.\",\n },\n destinationPath: {\n type: \"string\",\n description:\n \"Optional destination folder path like '/Documents/Restored' (mutually exclusive with destinationFolderId). If not provided, restores to original location.\",\n },\n },\n required: [\"fileId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n fileName: { type: \"string\", description: \"Name of the restored file\" },\n restored: {\n type: \"boolean\",\n description: \"Whether the file was restored\",\n },\n destinationFolder: {\n type: \"object\",\n description: \"Destination folder info (if moved)\",\n properties: {\n id: { type: \"string\" },\n name: { type: \"string\" },\n },\n },\n },\n },\n },\n {\n name: \"empty_trash\",\n description: \"Permanently delete all files in trash\",\n inputSchema: {\n type: \"object\",\n properties: {\n confirm: {\n type: \"boolean\",\n description: \"Must be true to confirm permanent deletion\",\n },\n driveId: {\n type: \"string\",\n description:\n \"Optional shared drive ID. If provided, empties trash of that shared drive instead of personal drive.\",\n },\n },\n required: [\"confirm\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n itemsDeleted: {\n type: \"number\",\n description: \"Number of items permanently deleted\",\n },\n driveId: {\n type: \"string\",\n description: \"Shared drive ID if specified\",\n },\n },\n },\n },\n {\n name: \"get_folder_tree\",\n description: \"Get folder tree structure (max depth 5, truncates at 100 items per folder)\",\n inputSchema: {\n type: \"object\",\n properties: {\n folderId: {\n type: \"string\",\n description:\n \"(optional) Folder ID to start from (defaults to root, mutually exclusive with folderPath)\",\n },\n folderPath: {\n type: \"string\",\n description:\n \"(optional) Folder path like '/Documents/Projects' (mutually exclusive with folderId)\",\n },\n depth: {\n type: \"number\",\n description:\n \"(optional, default: 2) Maximum depth to traverse (1-5). Higher values make more API calls.\",\n },\n },\n required: [],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Folder ID\" },\n name: { type: \"string\", description: \"Folder name\" },\n path: { type: \"string\", description: \"Folder path\" },\n children: {\n type: \"array\",\n description: \"Recursive array of files and folders\",\n items: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Item ID\" },\n name: { type: \"string\", description: \"Item name\" },\n type: { type: \"string\", description: \"'folder' or 'file'\" },\n mimeType: { type: \"string\", description: \"MIME type for files\" },\n children: {\n type: \"array\",\n description: \"Children (for folders only)\",\n },\n truncated: {\n type: \"boolean\",\n description: \"True if folder contents were truncated at 100 items\",\n },\n },\n },\n },\n truncated: {\n type: \"boolean\",\n description: \"True if root folder contents were truncated at 100 items\",\n },\n },\n },\n },\n];\n\n// Docs tools\nexport const docsTools: ToolDefinition[] = [\n {\n name: \"create_google_doc\",\n description: \"Create a new Google Doc\",\n inputSchema: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"Doc name\" },\n content: { type: \"string\", description: \"Doc content\" },\n parentFolderId: {\n type: \"string\",\n description: \"Parent folder ID (mutually exclusive with parentPath)\",\n },\n parentPath: {\n type: \"string\",\n description:\n \"Parent folder path like '/Documents/Reports' (creates folders if needed, mutually exclusive with parentFolderId)\",\n },\n },\n required: [\"name\", \"content\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Created document ID\" },\n name: { type: \"string\", description: \"Created document name\" },\n webViewLink: {\n type: \"string\",\n description: \"Link to view the document\",\n },\n },\n },\n },\n {\n name: \"update_google_doc\",\n description: \"Replace content in a Google Doc\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"Doc ID\" },\n content: { type: \"string\", description: \"New content\" },\n },\n required: [\"documentId\", \"content\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n title: { type: \"string\", description: \"Document title\" },\n updated: {\n type: \"boolean\",\n description: \"Whether the update succeeded\",\n },\n },\n },\n },\n {\n name: \"get_google_doc_content\",\n description: \"Read content from a Google Doc\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"Document ID\" },\n },\n required: [\"documentId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"Document ID\" },\n title: { type: \"string\", description: \"Document title\" },\n content: {\n type: \"array\",\n description: \"Document content segments with indices\",\n items: {\n type: \"object\",\n properties: {\n startIndex: {\n type: \"number\",\n description: \"Start character index\",\n },\n endIndex: { type: \"number\", description: \"End character index\" },\n text: { type: \"string\", description: \"Text content\" },\n },\n },\n },\n totalLength: { type: \"number\", description: \"Total character count\" },\n },\n },\n },\n {\n name: \"append_to_doc\",\n description: \"Append text to the end of a Google Doc\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"Document ID\" },\n text: { type: \"string\", description: \"Text to append\" },\n insertNewline: {\n type: \"boolean\",\n description: \"Insert newline before text (default: true)\",\n },\n },\n required: [\"documentId\", \"text\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n title: { type: \"string\", description: \"Document title\" },\n charactersAdded: {\n type: \"number\",\n description: \"Number of characters added\",\n },\n },\n },\n },\n {\n name: \"insert_text_in_doc\",\n description: \"Insert text at a position in a Doc\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"Document ID\" },\n text: { type: \"string\", description: \"Text to insert\" },\n index: {\n type: \"number\",\n description:\n \"Character index to insert at (1 = beginning of document content). Get indices from getGoogleDocContent.\",\n },\n },\n required: [\"documentId\", \"text\", \"index\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n title: { type: \"string\", description: \"Document title\" },\n index: { type: \"number\", description: \"Index where text was inserted\" },\n charactersInserted: {\n type: \"number\",\n description: \"Number of characters inserted\",\n },\n },\n },\n },\n {\n name: \"delete_text_in_doc\",\n description: \"Delete text range from a Google Doc\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"Document ID\" },\n startIndex: {\n type: \"number\",\n description: \"Start index of range to delete (inclusive, 1-based)\",\n },\n endIndex: {\n type: \"number\",\n description: \"End index of range to delete (exclusive, 1-based)\",\n },\n },\n required: [\"documentId\", \"startIndex\", \"endIndex\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n title: { type: \"string\", description: \"Document title\" },\n startIndex: { type: \"number\", description: \"Start of deleted range\" },\n endIndex: { type: \"number\", description: \"End of deleted range\" },\n charactersDeleted: {\n type: \"number\",\n description: \"Number of characters deleted\",\n },\n },\n },\n },\n {\n name: \"replace_text_in_doc\",\n description: \"Find and replace text in a Doc\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"Document ID\" },\n searchText: { type: \"string\", description: \"Text to search for\" },\n replaceText: {\n type: \"string\",\n description: \"Text to replace with (use empty string to delete)\",\n },\n matchCase: {\n type: \"boolean\",\n description: \"Match case (default: true)\",\n },\n },\n required: [\"documentId\", \"searchText\", \"replaceText\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n title: { type: \"string\", description: \"Document title\" },\n occurrencesChanged: {\n type: \"number\",\n description: \"Number of occurrences replaced\",\n },\n },\n },\n },\n {\n name: \"format_google_doc_range\",\n description: \"Format text and paragraphs in a Doc\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"Document ID\" },\n startIndex: {\n type: \"number\",\n description: \"Start index (1-based, optional - defaults to document start)\",\n },\n endIndex: {\n type: \"number\",\n description: \"End index (1-based, optional - defaults to document end)\",\n },\n // Text formatting\n bold: { type: \"boolean\", description: \"Make text bold\" },\n italic: { type: \"boolean\", description: \"Make text italic\" },\n underline: { type: \"boolean\", description: \"Underline text\" },\n strikethrough: { type: \"boolean\", description: \"Strikethrough text\" },\n fontSize: { type: \"number\", description: \"Font size in points\" },\n fontFamily: { type: \"string\", description: \"Font family name\" },\n foregroundColor: {\n type: \"object\",\n description: \"Text color (RGB values 0-1)\",\n properties: {\n red: { type: \"number\" },\n green: { type: \"number\" },\n blue: { type: \"number\" },\n },\n },\n // Paragraph formatting\n alignment: {\n type: \"string\",\n description: \"Text alignment\",\n enum: [\"START\", \"CENTER\", \"END\", \"JUSTIFIED\"],\n },\n lineSpacing: { type: \"number\", description: \"Line spacing multiplier\" },\n spaceAbove: {\n type: \"number\",\n description: \"Space above paragraph in points\",\n },\n spaceBelow: {\n type: \"number\",\n description: \"Space below paragraph in points\",\n },\n namedStyleType: {\n type: \"string\",\n description: \"Paragraph style\",\n enum: [\n \"NORMAL_TEXT\",\n \"TITLE\",\n \"SUBTITLE\",\n \"HEADING_1\",\n \"HEADING_2\",\n \"HEADING_3\",\n \"HEADING_4\",\n \"HEADING_5\",\n \"HEADING_6\",\n ],\n },\n },\n required: [\"documentId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n startIndex: { type: \"number\", description: \"Start of formatted range\" },\n endIndex: { type: \"number\", description: \"End of formatted range\" },\n formatsApplied: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"List of formats applied\",\n },\n },\n },\n },\n];\n\n// Sheets tools\nexport const sheetsTools: ToolDefinition[] = [\n {\n name: \"create_google_sheet\",\n description: \"Create a new Google Sheet\",\n inputSchema: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"Sheet name\" },\n data: {\n type: \"array\",\n description: \"Data as array of arrays\",\n items: { type: \"array\", items: { type: \"string\" } },\n },\n parentFolderId: {\n type: \"string\",\n description: \"Parent folder ID (mutually exclusive with parentPath)\",\n },\n parentPath: {\n type: \"string\",\n description:\n \"Parent folder path like '/Data/Spreadsheets' (creates folders if needed, mutually exclusive with parentFolderId)\",\n },\n valueInputOption: {\n type: \"string\",\n enum: [\"RAW\", \"USER_ENTERED\"],\n description:\n \"RAW (default): Values stored exactly as provided - formulas stored as text strings. Safe for untrusted data. USER_ENTERED: Values parsed like spreadsheet UI - formulas (=SUM, =IF, etc.) are evaluated. SECURITY WARNING: USER_ENTERED can execute formulas, only use with trusted data, never with user-provided input that could contain malicious formulas like =IMPORTDATA() or =IMPORTRANGE().\",\n },\n },\n required: [\"name\", \"data\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Created spreadsheet ID\" },\n name: { type: \"string\", description: \"Created spreadsheet name\" },\n },\n },\n },\n {\n name: \"update_google_sheet\",\n description: \"Update a Google Sheet range\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Sheet ID\" },\n range: {\n type: \"string\",\n description: \"Range to update (e.g., 'Sheet1!A1:C10')\",\n },\n data: {\n type: \"array\",\n description: \"2D array of values to write\",\n items: { type: \"array\", items: { type: \"string\" } },\n },\n valueInputOption: {\n type: \"string\",\n enum: [\"RAW\", \"USER_ENTERED\"],\n description:\n \"RAW (default): Values stored exactly as provided - formulas stored as text strings. Safe for untrusted data. USER_ENTERED: Values parsed like spreadsheet UI - formulas (=SUM, =IF, etc.) are evaluated. SECURITY WARNING: USER_ENTERED can execute formulas, only use with trusted data, never with user-provided input that could contain malicious formulas like =IMPORTDATA() or =IMPORTRANGE().\",\n },\n },\n required: [\"spreadsheetId\", \"range\", \"data\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n range: { type: \"string\", description: \"Range that was updated\" },\n updated: {\n type: \"boolean\",\n description: \"Whether the update succeeded\",\n },\n },\n },\n },\n {\n name: \"get_google_sheet_content\",\n description: \"Read content from a Google Sheet\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\n range: {\n type: \"string\",\n description:\n \"Range in A1 notation (e.g., 'Sheet1!A1:C10'). Optional - if omitted, returns all data from the first sheet.\",\n },\n },\n required: [\"spreadsheetId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\n range: { type: \"string\", description: \"Range that was retrieved\" },\n values: {\n type: \"array\",\n description: \"2D array of cell values (rows x columns)\",\n items: {\n type: \"array\",\n items: { type: \"string\", description: \"Cell value\" },\n },\n },\n rowCount: { type: \"number\", description: \"Number of rows returned\" },\n columnCount: {\n type: \"number\",\n description: \"Number of columns returned\",\n },\n },\n },\n },\n {\n name: \"format_google_sheet_cells\",\n description: \"Format cells in a Google Sheet\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\n range: {\n type: \"string\",\n description: \"Range to format (e.g., 'Sheet1!A1:C10' or 'A1:C10')\",\n },\n // Cell formatting\n backgroundColor: {\n type: \"object\",\n description: \"Background color (RGB values 0-1)\",\n properties: {\n red: { type: \"number\" },\n green: { type: \"number\" },\n blue: { type: \"number\" },\n },\n },\n horizontalAlignment: {\n type: \"string\",\n description: \"Horizontal alignment\",\n enum: [\"LEFT\", \"CENTER\", \"RIGHT\"],\n },\n verticalAlignment: {\n type: \"string\",\n description: \"Vertical alignment\",\n enum: [\"TOP\", \"MIDDLE\", \"BOTTOM\"],\n },\n wrapStrategy: {\n type: \"string\",\n description: \"Text wrapping\",\n enum: [\"OVERFLOW_CELL\", \"CLIP\", \"WRAP\"],\n },\n // Text formatting\n bold: { type: \"boolean\", description: \"Make text bold\" },\n italic: { type: \"boolean\", description: \"Make text italic\" },\n strikethrough: { type: \"boolean\", description: \"Strikethrough text\" },\n underline: { type: \"boolean\", description: \"Underline text\" },\n fontSize: { type: \"number\", description: \"Font size in points\" },\n fontFamily: { type: \"string\", description: \"Font family name\" },\n foregroundColor: {\n type: \"object\",\n description: \"Text color (RGB values 0-1)\",\n properties: {\n red: { type: \"number\" },\n green: { type: \"number\" },\n blue: { type: \"number\" },\n },\n },\n // Number formatting\n numberFormat: {\n type: \"object\",\n description: \"Number format settings\",\n properties: {\n pattern: {\n type: \"string\",\n description: \"Format pattern (e.g., '#,##0.00', 'yyyy-mm-dd', '$#,##0.00', '0.00%')\",\n },\n type: {\n type: \"string\",\n description: \"Format type\",\n enum: [\"NUMBER\", \"CURRENCY\", \"PERCENT\", \"DATE\", \"TIME\", \"DATE_TIME\", \"SCIENTIFIC\"],\n },\n },\n },\n // Border formatting\n borders: {\n type: \"object\",\n description: \"Border settings\",\n properties: {\n style: {\n type: \"string\",\n description: \"Border style\",\n enum: [\"SOLID\", \"DASHED\", \"DOTTED\", \"DOUBLE\"],\n },\n width: { type: \"number\", description: \"Border width (1-3)\" },\n color: {\n type: \"object\",\n description: \"Border color (RGB values 0-1)\",\n properties: {\n red: { type: \"number\" },\n green: { type: \"number\" },\n blue: { type: \"number\" },\n },\n },\n top: {\n type: \"boolean\",\n description: \"Apply to top border (default: true)\",\n },\n bottom: {\n type: \"boolean\",\n description: \"Apply to bottom border (default: true)\",\n },\n left: {\n type: \"boolean\",\n description: \"Apply to left border (default: true)\",\n },\n right: {\n type: \"boolean\",\n description: \"Apply to right border (default: true)\",\n },\n innerHorizontal: {\n type: \"boolean\",\n description: \"Apply to inner horizontal borders\",\n },\n innerVertical: {\n type: \"boolean\",\n description: \"Apply to inner vertical borders\",\n },\n },\n },\n },\n required: [\"spreadsheetId\", \"range\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n range: { type: \"string\", description: \"Range that was formatted\" },\n applied: {\n type: \"boolean\",\n description: \"Whether formatting was applied\",\n },\n },\n },\n },\n {\n name: \"merge_google_sheet_cells\",\n description: \"Merge cells in a Google Sheet\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\n range: {\n type: \"string\",\n description: \"Range to merge (e.g., 'A1:C3')\",\n },\n mergeType: {\n type: \"string\",\n description: \"Merge type\",\n enum: [\"MERGE_ALL\", \"MERGE_COLUMNS\", \"MERGE_ROWS\"],\n },\n },\n required: [\"spreadsheetId\", \"range\", \"mergeType\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n range: { type: \"string\", description: \"Range that was merged\" },\n mergeType: { type: \"string\", description: \"Type of merge performed\" },\n },\n },\n },\n {\n name: \"add_google_sheet_conditional_format\",\n description: \"Add conditional formatting to a Sheet\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\n range: {\n type: \"string\",\n description: \"Range to apply formatting (e.g., 'A1:C10')\",\n },\n condition: {\n type: \"object\",\n description: \"Condition configuration\",\n properties: {\n type: {\n type: \"string\",\n description: \"Condition type\",\n enum: [\n \"NUMBER_GREATER\",\n \"NUMBER_LESS\",\n \"TEXT_CONTAINS\",\n \"TEXT_STARTS_WITH\",\n \"TEXT_ENDS_WITH\",\n \"CUSTOM_FORMULA\",\n ],\n },\n value: {\n type: \"string\",\n description: \"Value to compare or formula\",\n },\n },\n },\n format: {\n type: \"object\",\n description: \"Format to apply when condition is true\",\n properties: {\n backgroundColor: {\n type: \"object\",\n properties: {\n red: { type: \"number\" },\n green: { type: \"number\" },\n blue: { type: \"number\" },\n },\n },\n textFormat: {\n type: \"object\",\n properties: {\n bold: { type: \"boolean\" },\n foregroundColor: {\n type: \"object\",\n properties: {\n red: { type: \"number\" },\n green: { type: \"number\" },\n blue: { type: \"number\" },\n },\n },\n },\n },\n },\n },\n },\n required: [\"spreadsheetId\", \"range\", \"condition\", \"format\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n range: {\n type: \"string\",\n description: \"Range where conditional format was applied\",\n },\n conditionType: {\n type: \"string\",\n description: \"Type of condition applied\",\n },\n },\n },\n },\n {\n name: \"sheet_tabs\",\n description: \"Manage tabs in a spreadsheet: list, create, delete, or rename\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\n action: {\n type: \"string\",\n enum: [\"list\", \"create\", \"delete\", \"rename\"],\n description: \"Action to perform\",\n },\n title: { type: \"string\", description: \"Tab title (required for create/delete)\" },\n index: { type: \"number\", description: \"(optional) Position for new tab (create only)\" },\n currentTitle: { type: \"string\", description: \"Current title (required for rename)\" },\n newTitle: { type: \"string\", description: \"New title (required for rename)\" },\n },\n required: [\"spreadsheetId\", \"action\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n action: { type: \"string\", description: \"Action performed\" },\n tabs: {\n type: \"array\",\n description: \"List of tabs (for list action)\",\n items: {\n type: \"object\",\n properties: {\n sheetId: { type: \"number\", description: \"Sheet ID\" },\n title: { type: \"string\", description: \"Tab title\" },\n index: { type: \"number\", description: \"Tab position\" },\n },\n },\n },\n sheetId: { type: \"number\", description: \"Sheet ID (for create/delete/rename)\" },\n title: { type: \"string\", description: \"Tab title\" },\n },\n },\n },\n];\n\n// Slides tools\nexport const slidesTools: ToolDefinition[] = [\n {\n name: \"create_google_slides\",\n description: \"Create a new Google Slides presentation\",\n inputSchema: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"Presentation name\" },\n slides: {\n type: \"array\",\n description: \"Array of slide objects\",\n items: {\n type: \"object\",\n properties: {\n title: { type: \"string\" },\n content: { type: \"string\" },\n },\n },\n },\n parentFolderId: {\n type: \"string\",\n description: \"Parent folder ID (mutually exclusive with parentPath)\",\n },\n parentPath: {\n type: \"string\",\n description:\n \"Parent folder path like '/Presentations/2024' (creates folders if needed, mutually exclusive with parentFolderId)\",\n },\n },\n required: [\"name\", \"slides\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Created presentation ID\" },\n name: { type: \"string\", description: \"Created presentation name\" },\n webViewLink: {\n type: \"string\",\n description: \"Link to view the presentation\",\n },\n },\n },\n },\n {\n name: \"update_google_slides\",\n description: \"Update a Google Slides presentation\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n slides: {\n type: \"array\",\n description: \"Array of slide objects to replace existing slides\",\n items: {\n type: \"object\",\n properties: {\n title: { type: \"string\" },\n content: { type: \"string\" },\n },\n },\n },\n },\n required: [\"presentationId\", \"slides\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n slideCount: {\n type: \"number\",\n description: \"Number of slides after update\",\n },\n webViewLink: {\n type: \"string\",\n description: \"Link to view the presentation\",\n },\n },\n },\n },\n {\n name: \"get_google_slides_content\",\n description: \"Read content from Google Slides\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n slideIndex: {\n type: \"number\",\n description: \"Specific slide index (optional)\",\n },\n },\n required: [\"presentationId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n title: { type: \"string\", description: \"Presentation title\" },\n slideCount: { type: \"number\", description: \"Total number of slides\" },\n slides: {\n type: \"array\",\n description: \"List of slides with their elements\",\n items: {\n type: \"object\",\n properties: {\n index: { type: \"number\", description: \"Slide index (0-based)\" },\n objectId: { type: \"string\", description: \"Slide object ID\" },\n elements: {\n type: \"array\",\n description: \"Elements on the slide\",\n items: {\n type: \"object\",\n properties: {\n objectId: {\n type: \"string\",\n description: \"Element object ID\",\n },\n type: {\n type: \"string\",\n description: \"Element type\",\n enum: [\"textBox\", \"shape\", \"image\", \"video\", \"table\"],\n },\n text: {\n type: \"string\",\n description: \"Text content (for text elements)\",\n },\n shapeType: {\n type: \"string\",\n description: \"Shape type (for shapes)\",\n },\n },\n },\n },\n },\n },\n },\n },\n },\n },\n {\n name: \"format_slides_text\",\n description: \"Format text styling in Google Slides\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n objectId: { type: \"string\", description: \"Text element object ID\" },\n startIndex: { type: \"number\", description: \"Start index (0-based, optional)\" },\n endIndex: { type: \"number\", description: \"End index (0-based, optional)\" },\n bold: { type: \"boolean\", description: \"Make text bold\" },\n italic: { type: \"boolean\", description: \"Make text italic\" },\n underline: { type: \"boolean\", description: \"Underline text\" },\n strikethrough: { type: \"boolean\", description: \"Strikethrough text\" },\n fontSize: { type: \"number\", description: \"Font size in points\" },\n fontFamily: { type: \"string\", description: \"Font family name\" },\n foregroundColor: {\n type: \"object\",\n description: \"Text color RGB (values 0-1)\",\n properties: {\n red: { type: \"number\" },\n green: { type: \"number\" },\n blue: { type: \"number\" },\n },\n },\n alignment: {\n type: \"string\",\n description: \"Text alignment\",\n enum: [\"START\", \"CENTER\", \"END\", \"JUSTIFIED\"],\n },\n lineSpacing: { type: \"number\", description: \"Line spacing multiplier\" },\n bulletStyle: {\n type: \"string\",\n description: \"Bullet style\",\n enum: [\"NONE\", \"DISC\", \"ARROW\", \"SQUARE\", \"DIAMOND\", \"STAR\", \"NUMBERED\"],\n },\n },\n required: [\"presentationId\", \"objectId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n objectId: { type: \"string\", description: \"Formatted text object ID\" },\n formatsApplied: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"List of formats applied\",\n },\n },\n },\n },\n {\n name: \"format_slides_shape\",\n description: \"Format shape fill and outline in Google Slides\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n objectId: { type: \"string\", description: \"Shape object ID\" },\n backgroundColor: {\n type: \"object\",\n description: \"Shape fill color RGBA (values 0-1)\",\n properties: {\n red: { type: \"number\" },\n green: { type: \"number\" },\n blue: { type: \"number\" },\n alpha: { type: \"number\" },\n },\n },\n outlineColor: {\n type: \"object\",\n description: \"Outline color RGB (values 0-1)\",\n properties: {\n red: { type: \"number\" },\n green: { type: \"number\" },\n blue: { type: \"number\" },\n },\n },\n outlineWeight: { type: \"number\", description: \"Outline thickness in points\" },\n outlineDashStyle: {\n type: \"string\",\n description: \"Outline dash style\",\n enum: [\"SOLID\", \"DOT\", \"DASH\", \"DASH_DOT\", \"LONG_DASH\", \"LONG_DASH_DOT\"],\n },\n },\n required: [\"presentationId\", \"objectId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n objectId: { type: \"string\", description: \"Formatted shape object ID\" },\n formatsApplied: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"List of formats applied\",\n },\n },\n },\n },\n {\n name: \"format_slide_background\",\n description: \"Set slide background color in Google Slides\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n pageObjectIds: {\n type: \"array\",\n description: \"Array of slide IDs to format\",\n items: { type: \"string\" },\n },\n backgroundColor: {\n type: \"object\",\n description: \"Background color RGBA (values 0-1)\",\n properties: {\n red: { type: \"number\" },\n green: { type: \"number\" },\n blue: { type: \"number\" },\n alpha: { type: \"number\" },\n },\n },\n },\n required: [\"presentationId\", \"pageObjectIds\", \"backgroundColor\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n slidesFormatted: { type: \"number\", description: \"Number of slides formatted\" },\n },\n },\n },\n {\n name: \"create_google_slides_text_box\",\n description: \"Create a text box in Google Slides\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n pageObjectId: { type: \"string\", description: \"Slide ID\" },\n text: { type: \"string\", description: \"Text content\" },\n x: {\n type: \"number\",\n description: \"X position in EMU (1 inch = 914400 EMU)\",\n },\n y: { type: \"number\", description: \"Y position in EMU\" },\n width: { type: \"number\", description: \"Width in EMU\" },\n height: { type: \"number\", description: \"Height in EMU\" },\n fontSize: { type: \"number\", description: \"Font size in points\" },\n bold: { type: \"boolean\", description: \"Make text bold\" },\n italic: { type: \"boolean\", description: \"Make text italic\" },\n },\n required: [\"presentationId\", \"pageObjectId\", \"text\", \"x\", \"y\", \"width\", \"height\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n objectId: { type: \"string\", description: \"Created text box object ID\" },\n pageObjectId: {\n type: \"string\",\n description: \"Slide where text box was created\",\n },\n },\n },\n },\n {\n name: \"create_google_slides_shape\",\n description: \"Create a shape in Google Slides\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n pageObjectId: { type: \"string\", description: \"Slide ID\" },\n shapeType: {\n type: \"string\",\n description: \"Shape type\",\n enum: [\"RECTANGLE\", \"ELLIPSE\", \"DIAMOND\", \"TRIANGLE\", \"STAR\", \"ROUND_RECTANGLE\", \"ARROW\"],\n },\n x: {\n type: \"number\",\n description: \"X position in EMU (1 inch = 914400 EMU)\",\n },\n y: { type: \"number\", description: \"Y position in EMU\" },\n width: { type: \"number\", description: \"Width in EMU\" },\n height: { type: \"number\", description: \"Height in EMU\" },\n backgroundColor: {\n type: \"object\",\n description: \"Fill color (RGBA values 0-1)\",\n properties: {\n red: { type: \"number\" },\n green: { type: \"number\" },\n blue: { type: \"number\" },\n alpha: { type: \"number\" },\n },\n },\n },\n required: [\"presentationId\", \"pageObjectId\", \"shapeType\", \"x\", \"y\", \"width\", \"height\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n objectId: { type: \"string\", description: \"Created shape object ID\" },\n pageObjectId: {\n type: \"string\",\n description: \"Slide where shape was created\",\n },\n shapeType: { type: \"string\", description: \"Type of shape created\" },\n },\n },\n },\n {\n name: \"slides_speaker_notes\",\n description: \"Get or update speaker notes for a slide\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n slideIndex: { type: \"number\", description: \"Slide index (0-based)\" },\n action: {\n type: \"string\",\n enum: [\"get\", \"update\"],\n description: \"Action to perform\",\n },\n notes: { type: \"string\", description: \"Notes content (required for update)\" },\n },\n required: [\"presentationId\", \"slideIndex\", \"action\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n action: { type: \"string\", description: \"Action performed\" },\n slideIndex: { type: \"number\", description: \"Slide index\" },\n notes: { type: \"string\", description: \"Speaker notes content\" },\n updated: { type: \"boolean\", description: \"Whether notes were updated (for update action)\" },\n },\n },\n },\n {\n name: \"list_slide_pages\",\n description: \"List slides in a presentation\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n },\n required: [\"presentationId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n pages: {\n type: \"array\",\n description: \"List of slide pages with metadata\",\n items: {\n type: \"object\",\n properties: {\n objectId: {\n type: \"string\",\n description: \"Page object ID (used for slide operations)\",\n },\n index: {\n type: \"number\",\n description: \"Slide position (0-indexed)\",\n },\n pageType: {\n type: \"string\",\n description: \"Page type: SLIDE, MASTER, or LAYOUT\",\n },\n title: {\n type: \"string\",\n description: \"Slide title if available\",\n },\n },\n },\n },\n },\n },\n },\n];\n\n// Unified smart tools\nexport const unifiedTools: ToolDefinition[] = [\n {\n name: \"create_file\",\n description: \"Create file (auto-detects type from name)\",\n inputSchema: {\n type: \"object\",\n properties: {\n name: {\n type: \"string\",\n description:\n \"File name with extension (e.g., 'report.docx', 'data.xlsx', 'deck.pptx', 'notes.txt')\",\n },\n content: {\n description:\n \"File content: string for docs/text, 2D array for sheets, array of {title, content} for slides\",\n oneOf: [\n {\n type: \"string\",\n description: \"Text content for docs or text files\",\n },\n {\n type: \"array\",\n description: \"2D array for sheets\",\n items: { type: \"array\", items: { type: \"string\" } },\n },\n {\n type: \"array\",\n description: \"Slides array\",\n items: {\n type: \"object\",\n properties: {\n title: { type: \"string\" },\n content: { type: \"string\" },\n },\n required: [\"title\", \"content\"],\n },\n },\n ],\n },\n parentFolderId: {\n type: \"string\",\n description: \"Parent folder ID (mutually exclusive with parentPath)\",\n },\n parentPath: {\n type: \"string\",\n description:\n \"Parent folder path like '/Documents/Reports' (creates folders if needed, mutually exclusive with parentFolderId)\",\n },\n type: {\n type: \"string\",\n description: \"Optional explicit type override\",\n enum: [\"doc\", \"sheet\", \"slides\", \"text\"],\n },\n },\n required: [\"name\", \"content\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Created file ID\" },\n name: { type: \"string\", description: \"Created file name\" },\n type: {\n type: \"string\",\n description: \"File type (doc, sheet, slides, or text)\",\n },\n mimeType: { type: \"string\", description: \"Google MIME type\" },\n webViewLink: { type: \"string\", description: \"Link to view the file\" },\n },\n },\n },\n {\n name: \"update_file\",\n description: \"Update file (auto-detects type)\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: {\n type: \"string\",\n description: \"File ID to update (mutually exclusive with filePath)\",\n },\n filePath: {\n type: \"string\",\n description: \"File path like '/Documents/report.docx' (mutually exclusive with fileId)\",\n },\n content: {\n description: \"New content: string for docs/text, 2D array for sheets\",\n oneOf: [\n { type: \"string\", description: \"Text content\" },\n {\n type: \"array\",\n description: \"2D array for sheets\",\n items: { type: \"array\", items: { type: \"string\" } },\n },\n ],\n },\n range: {\n type: \"string\",\n description:\n \"For sheets only: range to update (e.g., 'Sheet1!A1:C10'). Defaults to Sheet1!A1\",\n },\n },\n required: [\"content\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Updated file ID\" },\n name: { type: \"string\", description: \"File name\" },\n type: { type: \"string\", description: \"File type\" },\n updated: { type: \"boolean\", description: \"Whether update succeeded\" },\n },\n },\n },\n {\n name: \"get_file_content\",\n description: \"Get file content (auto-detects type)\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: {\n type: \"string\",\n description: \"File ID to read (mutually exclusive with filePath)\",\n },\n filePath: {\n type: \"string\",\n description: \"File path like '/Documents/report.docx' (mutually exclusive with fileId)\",\n },\n range: {\n type: \"string\",\n description:\n \"For sheets only: range to read (e.g., 'Sheet1!A1:C10'). Defaults to all data\",\n },\n },\n },\n outputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"File ID\" },\n name: { type: \"string\", description: \"File name\" },\n type: {\n type: \"string\",\n description: \"File type (doc, sheet, slides, text, or binary)\",\n },\n mimeType: { type: \"string\", description: \"MIME type\" },\n content: {\n description:\n \"File content: string for docs/text, 2D array for sheets, slides array for presentations\",\n },\n metadata: {\n type: \"object\",\n description: \"Additional metadata\",\n properties: {\n modifiedTime: { type: \"string\" },\n title: { type: \"string\" },\n size: { type: \"string\" },\n rowCount: { type: \"number\" },\n columnCount: { type: \"number\" },\n slideCount: { type: \"number\" },\n },\n },\n },\n },\n },\n];\n\n// Calendar tools\nexport const calendarTools: ToolDefinition[] = [\n {\n name: \"list_calendars\",\n description: \"List all calendars accessible to the user\",\n inputSchema: {\n type: \"object\",\n properties: {\n showHidden: {\n type: \"boolean\",\n description: \"Include hidden calendars (default: false)\",\n },\n showDeleted: {\n type: \"boolean\",\n description: \"Include deleted calendars (default: false)\",\n },\n },\n },\n outputSchema: {\n type: \"object\",\n properties: {\n calendars: {\n type: \"array\",\n description: \"List of calendars\",\n items: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Calendar ID\" },\n summary: { type: \"string\", description: \"Calendar name\" },\n description: { type: \"string\", description: \"Calendar description\" },\n primary: { type: \"boolean\", description: \"Whether this is the primary calendar\" },\n accessRole: {\n type: \"string\",\n description: \"Access role (owner, writer, reader, freeBusyReader)\",\n },\n timeZone: { type: \"string\", description: \"Calendar timezone\" },\n },\n },\n },\n },\n },\n },\n {\n name: \"list_events\",\n description: \"List calendar events (max 2500 per request)\",\n inputSchema: {\n type: \"object\",\n properties: {\n calendarId: {\n type: \"string\",\n description: \"(optional, default: 'primary') Calendar ID\",\n },\n timeMin: {\n type: \"string\",\n description:\n \"(optional) Start of time range (RFC3339 timestamp, e.g., 2024-01-15T00:00:00Z)\",\n },\n timeMax: {\n type: \"string\",\n description: \"(optional) End of time range (RFC3339 timestamp)\",\n },\n query: {\n type: \"string\",\n description: \"(optional) Free text search terms to filter events\",\n },\n maxResults: {\n type: \"number\",\n description: \"(optional, default: 250) Maximum events to return (max 2500)\",\n },\n pageToken: {\n type: \"string\",\n description: \"(optional) Token for pagination\",\n },\n singleEvents: {\n type: \"boolean\",\n description: \"(optional, default: true) Expand recurring events into instances\",\n },\n orderBy: {\n type: \"string\",\n enum: [\"startTime\", \"updated\"],\n description: \"(optional) Sort order (startTime requires singleEvents=true)\",\n },\n },\n },\n outputSchema: {\n type: \"object\",\n properties: {\n events: {\n type: \"array\",\n description: \"List of events\",\n items: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Event ID\" },\n summary: { type: \"string\", description: \"Event title\" },\n description: { type: \"string\", description: \"Event description\" },\n location: { type: \"string\", description: \"Event location\" },\n start: {\n type: \"object\",\n description: \"Start time\",\n properties: {\n dateTime: { type: \"string\", description: \"RFC3339 timestamp (timed events)\" },\n date: { type: \"string\", description: \"YYYY-MM-DD (all-day events)\" },\n timeZone: { type: \"string\", description: \"IANA timezone\" },\n },\n },\n end: {\n type: \"object\",\n description: \"End time\",\n properties: {\n dateTime: { type: \"string\", description: \"RFC3339 timestamp (timed events)\" },\n date: { type: \"string\", description: \"YYYY-MM-DD (all-day events)\" },\n timeZone: { type: \"string\", description: \"IANA timezone\" },\n },\n },\n status: { type: \"string\", description: \"Event status\" },\n htmlLink: { type: \"string\", description: \"Link to event in Google Calendar\" },\n hangoutLink: { type: \"string\", description: \"Google Meet link if present\" },\n },\n },\n },\n nextPageToken: {\n type: \"string\",\n description: \"Token for fetching next page\",\n },\n },\n },\n },\n {\n name: \"get_event\",\n description: \"Get details of a calendar event\",\n inputSchema: {\n type: \"object\",\n properties: {\n calendarId: {\n type: \"string\",\n description: \"Calendar ID (defaults to 'primary')\",\n },\n eventId: {\n type: \"string\",\n description: \"Event ID\",\n },\n },\n required: [\"eventId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Event ID\" },\n summary: { type: \"string\", description: \"Event title\" },\n description: { type: \"string\", description: \"Event description\" },\n location: { type: \"string\", description: \"Event location\" },\n start: {\n type: \"object\",\n description: \"Start time\",\n properties: {\n dateTime: { type: \"string\", description: \"RFC3339 timestamp (timed events)\" },\n date: { type: \"string\", description: \"YYYY-MM-DD (all-day events)\" },\n timeZone: { type: \"string\", description: \"IANA timezone\" },\n },\n },\n end: {\n type: \"object\",\n description: \"End time\",\n properties: {\n dateTime: { type: \"string\", description: \"RFC3339 timestamp (timed events)\" },\n date: { type: \"string\", description: \"YYYY-MM-DD (all-day events)\" },\n timeZone: { type: \"string\", description: \"IANA timezone\" },\n },\n },\n status: { type: \"string\", description: \"Event status\" },\n htmlLink: { type: \"string\", description: \"Link to event\" },\n hangoutLink: { type: \"string\", description: \"Google Meet link\" },\n attendees: {\n type: \"array\",\n description: \"Event attendees\",\n items: {\n type: \"object\",\n properties: {\n email: { type: \"string\" },\n displayName: { type: \"string\" },\n responseStatus: { type: \"string\" },\n },\n },\n },\n organizer: {\n type: \"object\",\n description: \"Event organizer\",\n properties: {\n email: { type: \"string\", description: \"Organizer email\" },\n displayName: { type: \"string\", description: \"Organizer name\" },\n self: { type: \"boolean\", description: \"Whether you are the organizer\" },\n },\n },\n recurrence: {\n type: \"array\",\n description: \"Recurrence rules (RRULE format)\",\n items: { type: \"string\" },\n },\n },\n },\n },\n {\n name: \"create_event\",\n description: \"Create a new calendar event\",\n inputSchema: {\n type: \"object\",\n properties: {\n calendarId: {\n type: \"string\",\n description: \"Calendar ID (defaults to 'primary')\",\n },\n summary: {\n type: \"string\",\n description: \"Event title\",\n },\n description: {\n type: \"string\",\n description: \"Event description\",\n },\n location: {\n type: \"string\",\n description: \"Event location\",\n },\n start: {\n type: \"object\",\n description:\n \"Start time. Use dateTime for timed events (RFC3339) or date for all-day (YYYY-MM-DD)\",\n properties: {\n dateTime: {\n type: \"string\",\n description: \"RFC3339 timestamp (e.g., 2024-01-15T09:00:00-05:00)\",\n },\n date: { type: \"string\", description: \"All-day date (YYYY-MM-DD)\" },\n timeZone: { type: \"string\", description: \"IANA timezone\" },\n },\n },\n end: {\n type: \"object\",\n description: \"End time (same format as start)\",\n properties: {\n dateTime: { type: \"string\" },\n date: { type: \"string\" },\n timeZone: { type: \"string\" },\n },\n },\n attendees: {\n type: \"array\",\n description: \"List of attendee email addresses\",\n items: {\n type: \"object\",\n properties: {\n email: { type: \"string\" },\n displayName: { type: \"string\" },\n optional: { type: \"boolean\" },\n },\n required: [\"email\"],\n },\n },\n addGoogleMeet: {\n type: \"boolean\",\n description: \"Add Google Meet video conference (default: false)\",\n },\n reminders: {\n type: \"array\",\n description: \"Custom reminders (overrides calendar defaults)\",\n items: {\n type: \"object\",\n properties: {\n method: { type: \"string\", enum: [\"email\", \"popup\"] },\n minutes: { type: \"number\", description: \"Minutes before event\" },\n },\n },\n },\n colorId: {\n type: \"string\",\n description: \"Event color ID (1-11)\",\n },\n recurrence: {\n type: \"array\",\n description: \"RRULE strings for recurring events\",\n items: { type: \"string\" },\n },\n sendUpdates: {\n type: \"string\",\n enum: [\"all\", \"externalOnly\", \"none\"],\n description: \"Who to send notifications to (default: all)\",\n },\n },\n required: [\"summary\", \"start\", \"end\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Created event ID\" },\n summary: { type: \"string\", description: \"Event title\" },\n htmlLink: { type: \"string\", description: \"Link to event\" },\n hangoutLink: { type: \"string\", description: \"Google Meet link if created\" },\n },\n },\n },\n {\n name: \"update_event\",\n description: \"Update an existing calendar event\",\n inputSchema: {\n type: \"object\",\n properties: {\n calendarId: {\n type: \"string\",\n description: \"Calendar ID (defaults to 'primary')\",\n },\n eventId: {\n type: \"string\",\n description: \"Event ID to update\",\n },\n summary: { type: \"string\", description: \"New event title\" },\n description: { type: \"string\", description: \"New description\" },\n location: { type: \"string\", description: \"New location\" },\n start: {\n type: \"object\",\n description: \"New start time\",\n properties: {\n dateTime: { type: \"string\" },\n date: { type: \"string\" },\n timeZone: { type: \"string\" },\n },\n },\n end: {\n type: \"object\",\n description: \"New end time\",\n properties: {\n dateTime: { type: \"string\" },\n date: { type: \"string\" },\n timeZone: { type: \"string\" },\n },\n },\n attendees: {\n type: \"array\",\n description: \"Replace attendee list\",\n items: {\n type: \"object\",\n properties: {\n email: { type: \"string\" },\n displayName: { type: \"string\" },\n optional: { type: \"boolean\" },\n },\n },\n },\n addGoogleMeet: {\n type: \"boolean\",\n description: \"Add Google Meet if not present\",\n },\n reminders: {\n type: \"array\",\n description: \"New custom reminders\",\n items: {\n type: \"object\",\n properties: {\n method: { type: \"string\", enum: [\"email\", \"popup\"] },\n minutes: { type: \"number\" },\n },\n },\n },\n colorId: { type: \"string\", description: \"New color ID (1-11)\" },\n sendUpdates: {\n type: \"string\",\n enum: [\"all\", \"externalOnly\", \"none\"],\n description: \"Who to notify of changes\",\n },\n },\n required: [\"eventId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Updated event ID\" },\n summary: { type: \"string\", description: \"Event title\" },\n htmlLink: { type: \"string\", description: \"Link to event\" },\n hangoutLink: { type: \"string\", description: \"Google Meet link\" },\n },\n },\n },\n {\n name: \"delete_event\",\n description: \"Delete a calendar event\",\n inputSchema: {\n type: \"object\",\n properties: {\n calendarId: {\n type: \"string\",\n description: \"Calendar ID (defaults to 'primary')\",\n },\n eventId: {\n type: \"string\",\n description: \"Event ID to delete\",\n },\n sendUpdates: {\n type: \"string\",\n enum: [\"all\", \"externalOnly\", \"none\"],\n description: \"Who to send cancellation notices to (default: all)\",\n },\n },\n required: [\"eventId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n deleted: { type: \"boolean\", description: \"Whether deletion succeeded\" },\n eventId: { type: \"string\", description: \"Deleted event ID\" },\n },\n },\n },\n {\n name: \"find_free_time\",\n description: \"Find free time slots across calendars (max 50 calendars)\",\n inputSchema: {\n type: \"object\",\n properties: {\n calendarIds: {\n type: \"array\",\n description:\n \"Calendar IDs to check (e.g., ['primary', 'user@example.com']). Max 50 calendars.\",\n items: { type: \"string\" },\n },\n timeMin: {\n type: \"string\",\n description: \"Start of search range (RFC3339 timestamp)\",\n },\n timeMax: {\n type: \"string\",\n description: \"End of search range (RFC3339 timestamp)\",\n },\n duration: {\n type: \"number\",\n description: \"Minimum free slot duration in minutes\",\n },\n timeZone: {\n type: \"string\",\n description: \"(optional, default: UTC) Timezone for results\",\n },\n },\n required: [\"calendarIds\", \"timeMin\", \"timeMax\", \"duration\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n freeSlots: {\n type: \"array\",\n description: \"Available time slots\",\n items: {\n type: \"object\",\n properties: {\n start: { type: \"string\", description: \"Slot start (ISO 8601)\" },\n end: { type: \"string\", description: \"Slot end (ISO 8601)\" },\n durationMinutes: { type: \"number\", description: \"Slot duration in minutes\" },\n },\n },\n },\n busyPeriods: {\n type: \"array\",\n description: \"Busy periods found\",\n items: {\n type: \"object\",\n properties: {\n start: { type: \"string\" },\n end: { type: \"string\" },\n },\n },\n },\n },\n },\n },\n];\n\n// Gmail tools\nexport const gmailTools: ToolDefinition[] = [\n // Core Email Operations\n {\n name: \"send_email\",\n description: \"Send an email\",\n inputSchema: {\n type: \"object\",\n properties: {\n to: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Recipient email addresses\",\n },\n subject: { type: \"string\", description: \"Email subject\" },\n body: { type: \"string\", description: \"Plain text email body\" },\n html: { type: \"string\", description: \"HTML email body (optional)\" },\n cc: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"CC recipients\",\n },\n bcc: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"BCC recipients\",\n },\n replyTo: { type: \"string\", description: \"Reply-to address\" },\n attachments: {\n type: \"array\",\n description: \"File attachments\",\n items: {\n type: \"object\",\n properties: {\n filename: { type: \"string\" },\n content: { type: \"string\", description: \"Base64-encoded content\" },\n mimeType: { type: \"string\" },\n },\n required: [\"filename\", \"content\"],\n },\n },\n threadId: { type: \"string\", description: \"Thread ID to reply to\" },\n inReplyTo: { type: \"string\", description: \"Message-ID for threading\" },\n },\n required: [\"to\", \"subject\", \"body\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Sent message ID\" },\n threadId: { type: \"string\", description: \"Thread ID\" },\n labelIds: { type: \"array\", items: { type: \"string\" } },\n },\n },\n },\n {\n name: \"draft_email\",\n description: \"Create a draft email (can be completed later)\",\n inputSchema: {\n type: \"object\",\n properties: {\n to: { type: \"array\", items: { type: \"string\" }, description: \"Recipients\" },\n subject: { type: \"string\", description: \"Subject\" },\n body: { type: \"string\", description: \"Plain text body\" },\n html: { type: \"string\", description: \"HTML body\" },\n cc: { type: \"array\", items: { type: \"string\" } },\n bcc: { type: \"array\", items: { type: \"string\" } },\n replyTo: { type: \"string\" },\n attachments: { type: \"array\" },\n threadId: { type: \"string\" },\n },\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Draft ID\" },\n messageId: { type: \"string\", description: \"Message ID\" },\n threadId: { type: \"string\" },\n },\n },\n },\n {\n name: \"read_email\",\n description: \"Read email content and metadata\",\n inputSchema: {\n type: \"object\",\n properties: {\n messageId: { type: \"string\", description: \"Email message ID\" },\n format: {\n type: \"string\",\n enum: [\"full\", \"metadata\", \"minimal\", \"raw\"],\n description: \"Response format (default: full)\",\n },\n contentFormat: {\n type: \"string\",\n enum: [\"full\", \"text\", \"headers\"],\n description:\n \"Content format: 'full' (default, includes HTML), 'text' (plain text only, smaller), 'headers' (metadata only, no body)\",\n },\n },\n required: [\"messageId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\" },\n threadId: { type: \"string\" },\n labelIds: { type: \"array\", items: { type: \"string\" } },\n headers: {\n type: \"object\",\n description: \"Email headers\",\n properties: {\n from: { type: \"string\", description: \"Sender email address\" },\n to: { type: \"string\", description: \"Recipient(s) email addresses\" },\n cc: { type: \"string\", description: \"CC recipients\" },\n subject: { type: \"string\", description: \"Email subject line\" },\n date: { type: \"string\", description: \"Send date (RFC 2822 format)\" },\n messageId: { type: \"string\", description: \"Email Message-ID header\" },\n },\n },\n body: {\n type: \"object\",\n properties: {\n text: { type: \"string\" },\n html: { type: \"string\" },\n },\n },\n attachments: { type: \"array\" },\n },\n },\n },\n {\n name: \"search_emails\",\n description: \"Search emails using Gmail query syntax (max 500 per request)\",\n inputSchema: {\n type: \"object\",\n properties: {\n query: { type: \"string\", description: \"Gmail search query\" },\n maxResults: {\n type: \"number\",\n description: \"(optional, default: 50) Maximum results (max 500)\",\n },\n pageToken: { type: \"string\", description: \"(optional) Pagination token\" },\n labelIds: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"(optional) Filter by label IDs\",\n },\n includeSpamTrash: {\n type: \"boolean\",\n description: \"(optional, default: false) Include spam and trash\",\n },\n },\n required: [\"query\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n messages: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n id: { type: \"string\" },\n threadId: { type: \"string\" },\n from: { type: \"string\" },\n subject: { type: \"string\" },\n date: { type: \"string\" },\n snippet: { type: \"string\" },\n },\n },\n },\n nextPageToken: { type: \"string\" },\n resultSizeEstimate: { type: \"number\" },\n },\n },\n },\n {\n name: \"delete_email\",\n description: \"Delete emails permanently (max 1000 IDs per request)\",\n inputSchema: {\n type: \"object\",\n properties: {\n messageId: {\n oneOf: [{ type: \"string\" }, { type: \"array\", items: { type: \"string\" }, maxItems: 1000 }],\n description: \"Message ID or array of IDs (max 1000)\",\n },\n },\n required: [\"messageId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n deleted: { type: \"number\", description: \"Number of messages deleted\" },\n messageIds: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"IDs of deleted messages\",\n },\n },\n },\n },\n {\n name: \"modify_email\",\n description: \"Add/remove labels on threads (max 1000 IDs per request)\",\n inputSchema: {\n type: \"object\",\n properties: {\n threadId: {\n oneOf: [{ type: \"string\" }, { type: \"array\", items: { type: \"string\" }, maxItems: 1000 }],\n description: \"Thread ID or array of IDs (max 1000)\",\n },\n addLabelIds: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"(optional) Label IDs to add\",\n },\n removeLabelIds: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"(optional) Label IDs to remove\",\n },\n },\n required: [\"threadId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Thread ID\" },\n messageCount: { type: \"number\", description: \"Number of messages in thread\" },\n labelIds: { type: \"array\", items: { type: \"string\" }, description: \"Current labels\" },\n },\n },\n },\n {\n name: \"download_attachment\",\n description: \"Download an email attachment to disk\",\n inputSchema: {\n type: \"object\",\n properties: {\n messageId: { type: \"string\", description: \"Email message ID\" },\n attachmentId: { type: \"string\", description: \"Attachment ID from readEmail\" },\n filename: { type: \"string\", description: \"Save filename (optional)\" },\n outputPath: { type: \"string\", description: \"Output directory (optional)\" },\n },\n required: [\"messageId\", \"attachmentId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n path: { type: \"string\", description: \"Saved file path\" },\n size: { type: \"number\", description: \"File size in bytes\" },\n },\n },\n },\n // Label Management\n {\n name: \"update_label\",\n description: \"Update an existing Gmail label\",\n inputSchema: {\n type: \"object\",\n properties: {\n labelId: { type: \"string\", description: \"Label ID to update\" },\n name: { type: \"string\", description: \"(optional) New name\" },\n messageListVisibility: {\n type: \"string\",\n enum: [\"show\", \"hide\"],\n description: \"(optional) Show/hide in message list\",\n },\n labelListVisibility: {\n type: \"string\",\n enum: [\"labelShow\", \"labelShowIfUnread\", \"labelHide\"],\n description: \"(optional) Label list visibility\",\n },\n backgroundColor: { type: \"string\", description: \"(optional) Background color\" },\n textColor: { type: \"string\", description: \"(optional) Text color\" },\n },\n required: [\"labelId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Label ID\" },\n name: { type: \"string\", description: \"Label name\" },\n updated: { type: \"boolean\", description: \"Whether the update succeeded\" },\n },\n },\n },\n {\n name: \"delete_label\",\n description: \"Delete a user-created label\",\n inputSchema: {\n type: \"object\",\n properties: {\n labelId: { type: \"string\", description: \"Label ID to delete\" },\n },\n required: [\"labelId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n deleted: { type: \"boolean\", description: \"Whether the deletion succeeded\" },\n labelId: { type: \"string\", description: \"Deleted label ID\" },\n },\n },\n },\n {\n name: \"list_labels\",\n description: \"List all Gmail labels (system and user-created)\",\n inputSchema: {\n type: \"object\",\n properties: {\n includeSystemLabels: {\n type: \"boolean\",\n description: \"Include INBOX, SENT, etc. (default: true)\",\n },\n },\n },\n outputSchema: {\n type: \"object\",\n properties: {\n labels: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n id: { type: \"string\" },\n name: { type: \"string\" },\n type: { type: \"string\" },\n messagesTotal: { type: \"number\" },\n messagesUnread: { type: \"number\" },\n },\n },\n },\n },\n },\n },\n {\n name: \"get_or_create_label\",\n description: \"Get or create a Gmail label\",\n inputSchema: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"Label name\" },\n messageListVisibility: { type: \"string\", enum: [\"show\", \"hide\"] },\n labelListVisibility: {\n type: \"string\",\n enum: [\"labelShow\", \"labelShowIfUnread\", \"labelHide\"],\n },\n backgroundColor: { type: \"string\" },\n textColor: { type: \"string\" },\n },\n required: [\"name\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\" },\n name: { type: \"string\" },\n created: { type: \"boolean\", description: \"True if newly created\" },\n },\n },\n },\n // Filter Management\n {\n name: \"create_filter\",\n description: \"Create an email filter\",\n inputSchema: {\n type: \"object\",\n properties: {\n // Direct mode\n criteria: {\n type: \"object\",\n description: \"Filter criteria (direct mode)\",\n properties: {\n from: { type: \"string\" },\n to: { type: \"string\" },\n subject: { type: \"string\" },\n query: { type: \"string\" },\n hasAttachment: { type: \"boolean\" },\n excludeChats: { type: \"boolean\" },\n size: { type: \"number\" },\n sizeComparison: { type: \"string\", enum: [\"larger\", \"smaller\"] },\n },\n },\n action: {\n type: \"object\",\n description: \"Actions (direct mode)\",\n properties: {\n addLabelIds: { type: \"array\", items: { type: \"string\" } },\n removeLabelIds: { type: \"array\", items: { type: \"string\" } },\n forward: { type: \"string\" },\n },\n },\n // Template mode\n template: {\n type: \"string\",\n enum: [\"fromSender\", \"withSubject\", \"withAttachments\", \"largeEmails\", \"mailingList\"],\n description: \"Use pre-built template instead of criteria/action\",\n },\n labelIds: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Labels (template mode)\",\n },\n archive: { type: \"boolean\", description: \"Archive matching emails (template mode)\" },\n email: { type: \"string\", description: \"Email for fromSender/mailingList template\" },\n subject: { type: \"string\", description: \"Subject for withSubject template\" },\n sizeBytes: { type: \"number\", description: \"Size for largeEmails template\" },\n listAddress: { type: \"string\", description: \"List address for mailingList template\" },\n },\n },\n outputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\" },\n template: { type: \"string\" },\n criteria: { type: \"object\" },\n action: { type: \"object\" },\n },\n },\n },\n {\n name: \"list_filters\",\n description: \"List filters or get specific filter details\",\n inputSchema: {\n type: \"object\",\n properties: {\n filterId: { type: \"string\", description: \"Optional: get specific filter\" },\n },\n },\n outputSchema: {\n type: \"object\",\n properties: {\n filters: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n id: { type: \"string\" },\n criteria: { type: \"object\" },\n action: { type: \"object\" },\n },\n },\n },\n },\n },\n },\n {\n name: \"delete_filter\",\n description: \"Delete an email filter\",\n inputSchema: {\n type: \"object\",\n properties: {\n filterId: { type: \"string\", description: \"Filter ID to delete\" },\n },\n required: [\"filterId\"],\n },\n outputSchema: {\n type: \"object\",\n properties: {\n deleted: { type: \"boolean\", description: \"Whether the deletion succeeded\" },\n filterId: { type: \"string\", description: \"Deleted filter ID\" },\n },\n },\n },\n];\n\nimport { isServiceEnabled, areUnifiedToolsEnabled, type ServiceName } from \"../config/index.js\";\n\n/** Map of service names to their tool definitions */\nexport const SERVICE_TOOL_MAP: Record<ServiceName, ToolDefinition[]> = {\n drive: driveTools,\n docs: docsTools,\n sheets: sheetsTools,\n slides: slidesTools,\n calendar: calendarTools,\n gmail: gmailTools,\n};\n\n/** Discovery tool for listing available tools */\nexport const discoveryTools: ToolDefinition[] = [\n {\n name: \"list_tools\",\n description: \"List available tools, optionally filtered by service or keyword\",\n inputSchema: {\n type: \"object\",\n properties: {\n service: {\n type: \"string\",\n enum: [\"drive\", \"docs\", \"sheets\", \"slides\", \"calendar\", \"gmail\", \"unified\"],\n description: \"(optional) Filter by service name\",\n },\n keyword: {\n type: \"string\",\n description: \"(optional) Filter by keyword in tool name or description\",\n },\n includeSchemas: {\n type: \"boolean\",\n description: \"(optional, default: false) Include full input/output schemas in response\",\n },\n },\n },\n outputSchema: {\n type: \"object\",\n properties: {\n tools: {\n type: \"array\",\n description: \"List of matching tools\",\n items: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"Tool name\" },\n description: { type: \"string\", description: \"Tool description\" },\n service: { type: \"string\", description: \"Service the tool belongs to\" },\n inputSchema: {\n type: \"object\",\n description: \"Input schema (if includeSchemas=true)\",\n },\n outputSchema: {\n type: \"object\",\n description: \"Output schema (if includeSchemas=true)\",\n },\n },\n },\n },\n totalCount: { type: \"number\", description: \"Total number of matching tools\" },\n services: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Available services\",\n },\n },\n },\n },\n];\n\n/**\n * Get all tool definitions combined into a single array.\n * Filters by enabled services (GOOGLE_WORKSPACE_SERVICES env var).\n * If not set, all services are enabled (backward compatible).\n */\nexport function getAllTools(): ToolDefinition[] {\n const tools: ToolDefinition[] = [];\n\n // Always include discovery tools\n tools.push(...discoveryTools);\n\n for (const [service, serviceTools] of Object.entries(SERVICE_TOOL_MAP)) {\n if (isServiceEnabled(service as ServiceName)) {\n tools.push(...serviceTools);\n }\n }\n\n // Unified tools require drive+docs+sheets+slides to all be enabled\n if (areUnifiedToolsEnabled()) {\n tools.push(...unifiedTools);\n }\n\n return tools;\n}\n", "/**\n * MCP Prompt definitions for common Google Drive workflows\n */\n\nexport interface PromptDefinition {\n name: string;\n description: string;\n arguments?: Array<{\n name: string;\n description: string;\n required?: boolean;\n }>;\n}\n\nexport interface PromptMessage {\n role: \"user\" | \"assistant\";\n content: {\n type: \"text\";\n text: string;\n };\n}\n\nexport const PROMPTS: PromptDefinition[] = [\n {\n name: \"organize-folder\",\n description:\n \"Organize files in a folder by type or date. Creates subfolders and moves files accordingly.\",\n arguments: [\n {\n name: \"folderId\",\n description: 'The ID of the folder to organize (use \"root\" for My Drive)',\n required: true,\n },\n {\n name: \"organizeBy\",\n description: 'How to organize: \"type\" (by file type) or \"date\" (by creation date)',\n required: true,\n },\n ],\n },\n {\n name: \"backup-folder\",\n description:\n \"Export all files in a folder to a local directory. Google Docs are exported as their native formats.\",\n arguments: [\n {\n name: \"folderId\",\n description: \"The ID of the folder to backup\",\n required: true,\n },\n {\n name: \"localPath\",\n description: \"Local directory path to save the backup\",\n required: true,\n },\n ],\n },\n {\n name: \"share-with-team\",\n description: \"Share multiple files with a list of email addresses with specified permissions.\",\n arguments: [\n {\n name: \"fileIds\",\n description: \"Comma-separated list of file IDs to share\",\n required: true,\n },\n {\n name: \"emails\",\n description: \"Comma-separated list of email addresses\",\n required: true,\n },\n {\n name: \"role\",\n description: \"Permission role: reader, commenter, or writer\",\n required: false,\n },\n ],\n },\n {\n name: \"cleanup-old-files\",\n description: \"Find and optionally delete files older than a specified number of days.\",\n arguments: [\n {\n name: \"folderId\",\n description: 'The folder to search (use \"root\" for My Drive, or omit for all files)',\n required: false,\n },\n {\n name: \"daysOld\",\n description: \"Minimum age in days for files to be considered old\",\n required: true,\n },\n {\n name: \"action\",\n description: 'Action to take: \"list\" (just show files) or \"trash\" (move to trash)',\n required: false,\n },\n ],\n },\n {\n name: \"migrate-format\",\n description:\n \"Convert legacy Microsoft Office files (.doc, .xls, .ppt) to Google Workspace formats.\",\n arguments: [\n {\n name: \"folderId\",\n description: 'The folder to search for files to convert (use \"root\" for My Drive)',\n required: false,\n },\n {\n name: \"fileTypes\",\n description:\n 'Comma-separated file types to convert: doc, xls, ppt (or \"all\" for all types)',\n required: false,\n },\n ],\n },\n];\n\n/**\n * Generate prompt messages for a given prompt name and arguments\n */\nexport function generatePromptMessages(\n promptName: string,\n args: Record<string, string>,\n): PromptMessage[] {\n switch (promptName) {\n case \"organize-folder\":\n return generateOrganizeFolderPrompt(args);\n case \"backup-folder\":\n return generateBackupFolderPrompt(args);\n case \"share-with-team\":\n return generateShareWithTeamPrompt(args);\n case \"cleanup-old-files\":\n return generateCleanupOldFilesPrompt(args);\n case \"migrate-format\":\n return generateMigrateFormatPrompt(args);\n default:\n throw new Error(`Unknown prompt: ${promptName}`);\n }\n}\n\nfunction generateOrganizeFolderPrompt(args: Record<string, string>): PromptMessage[] {\n const folderId = args.folderId || \"root\";\n const organizeBy = args.organizeBy || \"type\";\n\n const instructions =\n organizeBy === \"type\"\n ? `Please organize the files in folder \"${folderId}\" by their file type:\n\n1. First, use listFolder to get all files in the folder\n2. Create subfolders for each file type found (e.g., \"Documents\", \"Spreadsheets\", \"Images\", \"Videos\", \"Other\")\n3. Move each file to its appropriate subfolder using moveItem\n4. Report the results showing how many files were moved to each category\n\nFile type mappings:\n- Documents: .doc, .docx, .pdf, .txt, Google Docs\n- Spreadsheets: .xls, .xlsx, .csv, Google Sheets\n- Presentations: .ppt, .pptx, Google Slides\n- Images: .jpg, .jpeg, .png, .gif, .svg\n- Videos: .mp4, .mov, .avi\n- Audio: .mp3, .wav\n- Other: everything else`\n : `Please organize the files in folder \"${folderId}\" by their creation date:\n\n1. First, use listFolder to get all files in the folder\n2. For each file, check its creation date using getFileMetadata\n3. Create subfolders by year and month (e.g., \"2024/January\", \"2024/February\")\n4. Move each file to its appropriate date-based subfolder using moveItem\n5. Report the results showing how many files were organized`;\n\n return [\n {\n role: \"user\",\n content: {\n type: \"text\",\n text: instructions,\n },\n },\n ];\n}\n\nfunction generateBackupFolderPrompt(args: Record<string, string>): PromptMessage[] {\n const folderId = args.folderId;\n const localPath = args.localPath;\n\n return [\n {\n role: \"user\",\n content: {\n type: \"text\",\n text: `Please backup all files from Google Drive folder \"${folderId}\" to the local directory \"${localPath}\":\n\n1. Use listFolder to get all files in the folder (including subfolders recursively)\n2. For each file:\n - For Google Docs: export as .docx using exportFile\n - For Google Sheets: export as .xlsx using exportFile\n - For Google Slides: export as .pptx using exportFile\n - For other files: download using downloadFile\n3. Preserve the folder structure in the local directory\n4. Report progress and any errors encountered\n5. At the end, provide a summary of:\n - Total files backed up\n - Total size\n - Any files that failed to backup`,\n },\n },\n ];\n}\n\nfunction generateShareWithTeamPrompt(args: Record<string, string>): PromptMessage[] {\n const fileIds = args.fileIds;\n const emails = args.emails;\n const role = args.role || \"reader\";\n\n return [\n {\n role: \"user\",\n content: {\n type: \"text\",\n text: `Please share the following files with the team:\n\nFiles to share: ${fileIds}\nTeam members: ${emails}\nPermission level: ${role}\n\nSteps:\n1. For each file ID in the list, use shareFile to share with each email address\n2. Use role \"${role}\" for all shares\n3. Report the results showing:\n - Which files were successfully shared\n - Which email addresses received access\n - Any errors or files that couldn't be shared\n\nNote: If any file is already shared with a user, you may need to update their permission level.`,\n },\n },\n ];\n}\n\nfunction generateCleanupOldFilesPrompt(args: Record<string, string>): PromptMessage[] {\n const folderId = args.folderId || \"\";\n const daysOld = args.daysOld;\n const action = args.action || \"list\";\n\n const folderClause = folderId ? `in folder \"${folderId}\"` : \"across your entire Google Drive\";\n\n const actionInstructions =\n action === \"trash\"\n ? `4. For each file older than ${daysOld} days, use deleteItem to move it to trash\n5. Report the files that were trashed`\n : `4. Do NOT delete any files - only report what was found`;\n\n return [\n {\n role: \"user\",\n content: {\n type: \"text\",\n text: `Please find files ${folderClause} that are older than ${daysOld} days:\n\n1. Use search to find files with modifiedTime older than ${daysOld} days ago\n2. For each file found, get its metadata to show name, size, and last modified date\n3. Sort results by date (oldest first)\n${actionInstructions}\n\nReport format:\n- File name\n- Size\n- Last modified date\n- Location (parent folder)\n\nTotal count and size of old files found.`,\n },\n },\n ];\n}\n\nfunction generateMigrateFormatPrompt(args: Record<string, string>): PromptMessage[] {\n const folderId = args.folderId || \"root\";\n const fileTypes = args.fileTypes || \"all\";\n\n const typeFilter =\n fileTypes === \"all\"\n ? \"Microsoft Office files (.doc, .docx, .xls, .xlsx, .ppt, .pptx)\"\n : fileTypes\n .split(\",\")\n .map((t) => `.${t.trim()}`)\n .join(\", \");\n\n return [\n {\n role: \"user\",\n content: {\n type: \"text\",\n text: `Please find and convert legacy Office files to Google Workspace formats in folder \"${folderId}\":\n\nTarget file types: ${typeFilter}\n\nSteps:\n1. Use search to find files matching the target types in the specified folder\n2. For each file found, report:\n - Current file name and type\n - File size\n - Last modified date\n3. Ask for confirmation before proceeding with conversion\n4. To convert a file:\n - Upload it with convert=true option to create a Google Docs/Sheets/Slides version\n - The original file will remain (user can delete it later if desired)\n5. Report conversion results:\n - Successfully converted files\n - Any files that failed to convert\n - Total storage impact (Google Workspace files don't count against quota)\n\nNote: This creates NEW Google Workspace files alongside the originals. Original files are preserved.`,\n },\n },\n ];\n}\n", "import type { drive_v3 } from \"googleapis\";\nimport {\n log,\n successResponse,\n structuredResponse,\n errorResponse,\n withTimeout,\n withRetry,\n elicitFileSelection,\n elicitConfirmation,\n formatDisambiguationOptions,\n validateArgs,\n toToon,\n} from \"../utils/index.js\";\nimport type { ToolResponse } from \"../utils/index.js\";\nimport {\n escapeQueryString,\n combineQueries,\n buildFullTextQuery,\n buildNameQuery,\n} from \"../utils/gdrive-query.js\";\nimport { formatBytes } from \"../utils/format.js\";\nimport {\n GetFolderTreeSchema,\n SearchSchema,\n CreateTextFileSchema,\n UpdateTextFileSchema,\n CreateFolderSchema,\n ListFolderSchema,\n DeleteItemSchema,\n RenameItemSchema,\n MoveItemSchema,\n CopyFileSchema,\n GetFileMetadataSchema,\n ExportFileSchema,\n ShareFileSchema,\n GetSharingSchema,\n ListRevisionsSchema,\n RestoreRevisionSchema,\n DownloadFileSchema,\n UploadFileSchema,\n GetStorageQuotaSchema,\n StarFileSchema,\n ResolveFilePathSchema,\n BatchDeleteSchema,\n BatchRestoreSchema,\n BatchMoveSchema,\n BatchShareSchema,\n RemovePermissionSchema,\n ListTrashSchema,\n RestoreFromTrashSchema,\n EmptyTrashSchema,\n} from \"../schemas/index.js\";\nimport {\n FOLDER_MIME_TYPE,\n TEXT_MIME_TYPES,\n getMimeTypeFromFilename,\n validateTextFileExtension,\n resolveFolderId,\n resolveOptionalFolderPath,\n checkFileExists,\n processBatchOperation,\n} from \"./helpers.js\";\nimport type { HandlerContext } from \"./helpers.js\";\n\nexport async function handleSearch(drive: drive_v3.Drive, args: unknown): Promise<ToolResponse> {\n const validation = validateArgs(SearchSchema, args);\n if (!validation.success) return validation.response;\n const { query: userQuery, searchType, pageSize, pageToken } = validation.data;\n\n // Build base query based on searchType\n let baseQuery: string;\n switch (searchType) {\n case \"name_exact\":\n baseQuery = buildNameQuery(userQuery, true); // name = 'query'\n break;\n case \"name\":\n baseQuery = buildNameQuery(userQuery, false); // name contains 'query'\n break;\n default:\n baseQuery = buildFullTextQuery(userQuery); // fullText contains 'query'\n }\n const formattedQuery = combineQueries(baseQuery, \"trashed = false\");\n\n const res = await drive.files.list({\n q: formattedQuery,\n pageSize: Math.min(pageSize || 50, 100),\n pageToken: pageToken,\n fields: \"nextPageToken, files(id, name, mimeType, modifiedTime, size)\",\n includeItemsFromAllDrives: true,\n supportsAllDrives: true,\n });\n\n const files =\n res.data.files?.map((f: drive_v3.Schema$File) => ({\n id: f.id,\n name: f.name,\n mimeType: f.mimeType,\n modifiedTime: f.modifiedTime,\n size: f.size,\n })) || [];\n\n log(\"Search results\", {\n query: userQuery,\n resultCount: files.length,\n });\n\n let textResponse = `Found ${files.length} files:\\n\\n${toToon({ files })}`;\n if (res.data.nextPageToken) {\n textResponse += `\\n\\nMore results available. Use pageToken: ${res.data.nextPageToken}`;\n }\n\n return structuredResponse(textResponse, {\n files,\n nextPageToken: res.data.nextPageToken || null,\n });\n}\n\nexport async function handleCreateTextFile(\n drive: drive_v3.Drive,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(CreateTextFileSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n validateTextFileExtension(data.name);\n const parentFolderId = await resolveOptionalFolderPath(\n drive,\n data.parentFolderId,\n data.parentPath,\n );\n\n // Check if file already exists\n const existingFileId = await checkFileExists(drive, data.name, parentFolderId);\n if (existingFileId) {\n return errorResponse(\n `A file named \"${data.name}\" already exists in this location. ` +\n `To update it, use updateTextFile with fileId: ${existingFileId}`,\n );\n }\n\n const fileMetadata = {\n name: data.name,\n mimeType: getMimeTypeFromFilename(data.name),\n parents: [parentFolderId],\n };\n\n log(\"About to create file\", { driveExists: !!drive });\n\n const file = await drive.files.create({\n requestBody: fileMetadata,\n media: {\n mimeType: fileMetadata.mimeType,\n body: data.content,\n },\n supportsAllDrives: true,\n });\n\n log(\"File created successfully\", { fileId: file.data?.id });\n return successResponse(\n `Created file: ${file.data?.name || data.name}\\nID: ${file.data?.id || \"unknown\"}`,\n );\n}\n\nexport async function handleUpdateTextFile(\n drive: drive_v3.Drive,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(UpdateTextFileSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Check file MIME type\n const existingFile = await drive.files.get({\n fileId: data.fileId,\n fields: \"mimeType, name, parents\",\n supportsAllDrives: true,\n });\n\n const currentMimeType = existingFile.data.mimeType || \"text/plain\";\n if (!Object.values(TEXT_MIME_TYPES).includes(currentMimeType)) {\n return errorResponse(\n `File \"${existingFile.data.name}\" (${data.fileId}) is not a text or markdown file. ` +\n `Current type: ${currentMimeType}. Supported types: text/plain, text/markdown.`,\n );\n }\n\n const updateMetadata: { name?: string; mimeType?: string } = {};\n if (data.name) {\n validateTextFileExtension(data.name);\n updateMetadata.name = data.name;\n updateMetadata.mimeType = getMimeTypeFromFilename(data.name);\n }\n\n const updatedFile = await drive.files.update({\n fileId: data.fileId,\n requestBody: updateMetadata,\n media: {\n mimeType: updateMetadata.mimeType || currentMimeType,\n body: data.content,\n },\n fields: \"id, name, modifiedTime, webViewLink\",\n supportsAllDrives: true,\n });\n\n return successResponse(\n `Updated file: ${updatedFile.data.name}\\nModified: ${updatedFile.data.modifiedTime}`,\n );\n}\n\nexport async function handleCreateFolder(\n drive: drive_v3.Drive,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(CreateFolderSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n const parentFolderId = await resolveOptionalFolderPath(drive, data.parent, data.parentPath);\n\n // Check if folder already exists\n const existingFolderId = await checkFileExists(drive, data.name, parentFolderId);\n if (existingFolderId) {\n return errorResponse(\n `A folder named \"${data.name}\" already exists in this location. ` +\n `Folder ID: ${existingFolderId}`,\n );\n }\n\n const folderMetadata = {\n name: data.name,\n mimeType: FOLDER_MIME_TYPE,\n parents: [parentFolderId],\n };\n\n const folder = await drive.files.create({\n requestBody: folderMetadata,\n fields: \"id, name, webViewLink\",\n supportsAllDrives: true,\n });\n\n log(\"Folder created successfully\", {\n folderId: folder.data.id,\n name: folder.data.name,\n });\n\n return successResponse(`Created folder: ${folder.data.name}\\nID: ${folder.data.id}`);\n}\n\nexport async function handleListFolder(\n drive: drive_v3.Drive,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(ListFolderSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Default to root if no folder specified\n const targetFolderId = data.folderId || \"root\";\n\n try {\n const res = await drive.files.list({\n q: `'${targetFolderId}' in parents and trashed = false`,\n pageSize: Math.min(data.pageSize || 50, 100),\n pageToken: data.pageToken,\n fields: \"nextPageToken, files(id, name, mimeType, modifiedTime, size)\",\n orderBy: \"name\",\n includeItemsFromAllDrives: true,\n supportsAllDrives: true,\n });\n\n const files = res.data.files || [];\n const formattedFiles = files\n .map((file: drive_v3.Schema$File) => {\n const isFolder = file.mimeType === FOLDER_MIME_TYPE;\n return `${isFolder ? \"\uD83D\uDCC1\" : \"\uD83D\uDCC4\"} ${file.name} (ID: ${file.id})`;\n })\n .join(\"\\n\");\n\n let response = `Contents of folder:\\n\\n${formattedFiles}`;\n if (res.data.nextPageToken) {\n response += `\\n\\nMore items available. Use pageToken: ${res.data.nextPageToken}`;\n }\n\n return successResponse(response);\n } catch (error) {\n // Handle 404 error with clearer message including folder ID\n if (error instanceof Error && error.message.includes(\"not found\")) {\n return errorResponse(`Folder not found: ${targetFolderId}`, { code: \"NOT_FOUND\" });\n }\n throw error;\n }\n}\n\nexport async function handleDeleteItem(\n drive: drive_v3.Drive,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(DeleteItemSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n const item = await drive.files.get({\n fileId: data.itemId,\n fields: \"name, mimeType\",\n supportsAllDrives: true,\n });\n\n // If it's a folder, count its contents before deleting\n let countInfo = \"\";\n if (item.data.mimeType === FOLDER_MIME_TYPE) {\n const contents = await drive.files.list({\n q: `'${data.itemId}' in parents and trashed = false`,\n fields: \"files(id, mimeType)\",\n pageSize: 1000,\n supportsAllDrives: true,\n includeItemsFromAllDrives: true,\n });\n\n const files = contents.data.files || [];\n const fileCount = files.filter((f) => f.mimeType !== FOLDER_MIME_TYPE).length;\n const folderCount = files.filter((f) => f.mimeType === FOLDER_MIME_TYPE).length;\n\n if (fileCount > 0 || folderCount > 0) {\n const parts: string[] = [];\n if (fileCount > 0) parts.push(`${fileCount} file${fileCount !== 1 ? \"s\" : \"\"}`);\n if (folderCount > 0) parts.push(`${folderCount} subfolder${folderCount !== 1 ? \"s\" : \"\"}`);\n countInfo = ` (contains ${parts.join(\", \")})`;\n }\n }\n\n // Move to trash instead of permanent deletion\n await drive.files.update({\n fileId: data.itemId,\n requestBody: { trashed: true },\n supportsAllDrives: true,\n });\n\n log(\"Item moved to trash successfully\", {\n itemId: data.itemId,\n name: item.data.name,\n });\n return successResponse(`Moved \"${item.data.name}\" to trash${countInfo}`);\n}\n\nexport async function handleRenameItem(\n drive: drive_v3.Drive,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(RenameItemSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // If it's a text file, check extension\n const item = await drive.files.get({\n fileId: data.itemId,\n fields: \"name, mimeType\",\n supportsAllDrives: true,\n });\n\n if (Object.values(TEXT_MIME_TYPES).includes(item.data.mimeType || \"\")) {\n validateTextFileExtension(data.newName);\n }\n\n const updatedItem = await drive.files.update({\n fileId: data.itemId,\n requestBody: { name: data.newName },\n fields: \"id, name, modifiedTime\",\n supportsAllDrives: true,\n });\n\n return successResponse(`Successfully renamed \"${item.data.name}\" to \"${updatedItem.data.name}\"`);\n}\n\nexport async function handleMoveItem(drive: drive_v3.Drive, args: unknown): Promise<ToolResponse> {\n const validation = validateArgs(MoveItemSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n const destinationFolderId = await resolveOptionalFolderPath(\n drive,\n data.destinationFolderId,\n data.destinationPath,\n );\n\n // Check we aren't moving a folder into itself\n if (destinationFolderId === data.itemId) {\n return errorResponse(\"Cannot move a folder into itself.\");\n }\n\n const item = await drive.files.get({\n fileId: data.itemId,\n fields: \"name, parents\",\n supportsAllDrives: true,\n });\n\n // Perform move\n await drive.files.update({\n fileId: data.itemId,\n addParents: destinationFolderId,\n removeParents: item.data.parents?.join(\",\") || \"\",\n fields: \"id, name, parents\",\n supportsAllDrives: true,\n });\n\n // Get the destination folder name for a nice response\n const destinationFolder = await drive.files.get({\n fileId: destinationFolderId,\n fields: \"name\",\n supportsAllDrives: true,\n });\n\n return successResponse(\n `Successfully moved \"${item.data.name}\" to \"${destinationFolder.data.name}\"`,\n );\n}\n\nexport async function handleCopyFile(drive: drive_v3.Drive, args: unknown): Promise<ToolResponse> {\n const validation = validateArgs(CopyFileSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Get source file metadata\n const sourceFile = await drive.files.get({\n fileId: data.sourceFileId,\n fields: \"name, parents\",\n supportsAllDrives: true,\n });\n\n const destinationName = data.destinationName || `Copy of ${sourceFile.data.name}`;\n const destinationFolderId = data.destinationFolderId\n ? await resolveFolderId(drive, data.destinationFolderId)\n : sourceFile.data.parents?.[0] || \"root\";\n\n // Check if destination name already exists\n const existingFileId = await checkFileExists(drive, destinationName, destinationFolderId);\n if (existingFileId) {\n return errorResponse(\n `A file named \"${destinationName}\" already exists in the destination folder. ` +\n `Existing file ID: ${existingFileId}`,\n );\n }\n\n // Copy the file\n const copiedFile = await drive.files.copy({\n fileId: data.sourceFileId,\n requestBody: {\n name: destinationName,\n parents: [destinationFolderId],\n },\n fields: \"id, name, webViewLink\",\n supportsAllDrives: true,\n });\n\n log(\"File copied successfully\", {\n sourceId: data.sourceFileId,\n newId: copiedFile.data.id,\n });\n\n return successResponse(\n `Copied file: ${copiedFile.data.name}\\nNew ID: ${copiedFile.data.id}\\nLink: ${copiedFile.data.webViewLink}`,\n );\n}\n\nexport async function handleGetFileMetadata(\n drive: drive_v3.Drive,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(GetFileMetadataSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n const file = await withTimeout(\n drive.files.get({\n fileId: data.fileId,\n fields:\n \"id, name, mimeType, size, createdTime, modifiedTime, owners, shared, webViewLink, parents, description, starred\",\n supportsAllDrives: true,\n }),\n 30000,\n \"Get file metadata\",\n );\n\n const metadata = file.data;\n const ownerNames =\n metadata.owners?.map((o) => o.displayName || o.emailAddress).join(\", \") || \"Unknown\";\n const sizeStr = formatBytes(metadata.size);\n\n const textResponse = [\n `Name: ${metadata.name}`,\n `ID: ${metadata.id}`,\n `Type: ${metadata.mimeType}`,\n `Size: ${sizeStr}`,\n `Created: ${metadata.createdTime}`,\n `Modified: ${metadata.modifiedTime}`,\n `Owner(s): ${ownerNames}`,\n `Shared: ${metadata.shared ? \"Yes\" : \"No\"}`,\n `Starred: ${metadata.starred ? \"Yes\" : \"No\"}`,\n metadata.description ? `Description: ${metadata.description}` : null,\n metadata.parents ? `Parent folder(s): ${metadata.parents.join(\", \")}` : null,\n `Link: ${metadata.webViewLink}`,\n ]\n .filter(Boolean)\n .join(\"\\n\");\n\n return structuredResponse(textResponse, {\n id: metadata.id,\n name: metadata.name,\n mimeType: metadata.mimeType,\n size: metadata.size,\n createdTime: metadata.createdTime,\n modifiedTime: metadata.modifiedTime,\n owners: metadata.owners?.map((o) => ({\n displayName: o.displayName,\n emailAddress: o.emailAddress,\n })),\n shared: metadata.shared,\n starred: metadata.starred,\n description: metadata.description,\n webViewLink: metadata.webViewLink,\n parents: metadata.parents,\n });\n}\n\nconst EXPORT_MIME_TYPES: Record<string, string> = {\n pdf: \"application/pdf\",\n docx: \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n xlsx: \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n pptx: \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\n csv: \"text/csv\",\n tsv: \"text/tab-separated-values\",\n odt: \"application/vnd.oasis.opendocument.text\",\n ods: \"application/vnd.oasis.opendocument.spreadsheet\",\n odp: \"application/vnd.oasis.opendocument.presentation\",\n};\n\nconst GOOGLE_DOC_FORMATS = [\"pdf\", \"docx\", \"odt\"];\nconst GOOGLE_SHEET_FORMATS = [\"pdf\", \"xlsx\", \"csv\", \"tsv\", \"ods\"];\nconst GOOGLE_SLIDES_FORMATS = [\"pdf\", \"pptx\", \"odp\"];\n\nexport async function handleExportFile(\n drive: drive_v3.Drive,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(ExportFileSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Get file metadata to determine type\n const file = await drive.files.get({\n fileId: data.fileId,\n fields: \"name, mimeType\",\n supportsAllDrives: true,\n });\n\n const mimeType = file.data.mimeType || \"\";\n const fileName = file.data.name || \"export\";\n\n // Validate format is compatible with file type\n let validFormats: string[];\n if (mimeType === \"application/vnd.google-apps.document\") {\n validFormats = GOOGLE_DOC_FORMATS;\n } else if (mimeType === \"application/vnd.google-apps.spreadsheet\") {\n validFormats = GOOGLE_SHEET_FORMATS;\n } else if (mimeType === \"application/vnd.google-apps.presentation\") {\n validFormats = GOOGLE_SLIDES_FORMATS;\n } else {\n return errorResponse(\n `File \"${fileName}\" is not a Google Doc, Sheet, or Slides. ` +\n `Cannot export ${mimeType} files. Use this tool only for Google Workspace files.`,\n );\n }\n\n if (!validFormats.includes(data.format)) {\n return errorResponse(\n `Cannot export Google ${mimeType.split(\".\").pop()} to ${data.format}. ` +\n `Valid formats: ${validFormats.join(\", \")}`,\n );\n }\n\n const exportMimeType = EXPORT_MIME_TYPES[data.format];\n\n // Export the file\n const response = await drive.files.export(\n { fileId: data.fileId, mimeType: exportMimeType },\n { responseType: \"arraybuffer\" },\n );\n\n const buffer = Buffer.from(response.data as ArrayBuffer);\n\n // If outputPath is provided, save to file\n if (data.outputPath) {\n const fs = await import(\"fs/promises\");\n const path = await import(\"path\");\n\n const outputFileName = `${fileName}.${data.format}`;\n const fullPath = path.join(data.outputPath, outputFileName);\n\n await fs.writeFile(fullPath, buffer);\n\n log(\"File exported successfully\", {\n fileId: data.fileId,\n outputPath: fullPath,\n });\n return successResponse(`Exported \"${fileName}\" to: ${fullPath}`);\n }\n\n // Otherwise return base64-encoded content\n const base64Content = buffer.toString(\"base64\");\n\n log(\"File exported successfully\", {\n fileId: data.fileId,\n format: data.format,\n });\n return successResponse(\n `Exported \"${fileName}\" as ${data.format}\\n\\n` +\n `Base64 content (${buffer.length} bytes):\\n${base64Content}`,\n );\n}\n\n// -----------------------------------------------------------------------------\n// SHARING HANDLERS\n// -----------------------------------------------------------------------------\n\nexport async function handleShareFile(drive: drive_v3.Drive, args: unknown): Promise<ToolResponse> {\n const validation = validateArgs(ShareFileSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Validate emailAddress required for user/group\n if ((data.type === \"user\" || data.type === \"group\") && !data.emailAddress) {\n return errorResponse(`Email address is required when sharing with type \"${data.type}\"`);\n }\n\n // Validate domain required for domain type\n if (data.type === \"domain\" && !data.domain) {\n return errorResponse('Domain is required when sharing with type \"domain\"');\n }\n\n // Get file name for response\n const file = await drive.files.get({\n fileId: data.fileId,\n fields: \"name\",\n supportsAllDrives: true,\n });\n\n const permissionBody: {\n role: string;\n type: string;\n emailAddress?: string;\n domain?: string;\n } = {\n role: data.role,\n type: data.type,\n };\n\n if (data.emailAddress) {\n permissionBody.emailAddress = data.emailAddress;\n }\n if (data.domain) {\n permissionBody.domain = data.domain;\n }\n\n const createParams: drive_v3.Params$Resource$Permissions$Create = {\n fileId: data.fileId,\n requestBody: permissionBody,\n supportsAllDrives: true,\n };\n\n // Only include notification params for user/group types (Google rejects for anyone/domain)\n if (data.type === \"user\" || data.type === \"group\") {\n createParams.sendNotificationEmail = data.sendNotificationEmail;\n if (data.emailMessage) {\n createParams.emailMessage = data.emailMessage;\n }\n }\n\n const permission = await drive.permissions.create(createParams);\n\n log(\"File shared successfully\", {\n fileId: data.fileId,\n permissionId: permission.data.id,\n });\n\n let targetDesc = \"\";\n if (data.type === \"anyone\") {\n targetDesc = \"anyone with the link\";\n } else if (data.type === \"domain\") {\n targetDesc = `anyone in ${data.domain}`;\n } else {\n targetDesc = data.emailAddress || \"\";\n }\n\n return successResponse(\n `Shared \"${file.data.name}\" with ${targetDesc} as ${data.role}\\n` +\n `Permission ID: ${permission.data.id}`,\n );\n}\n\nexport async function handleGetSharing(\n drive: drive_v3.Drive,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(GetSharingSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Get file name\n const file = await withTimeout(\n drive.files.get({\n fileId: data.fileId,\n fields: \"name, webViewLink\",\n supportsAllDrives: true,\n }),\n 30000,\n \"Get file info\",\n );\n\n // Get permissions\n const permissions = await withTimeout(\n drive.permissions.list({\n fileId: data.fileId,\n fields: \"permissions(id, role, type, emailAddress, domain, displayName)\",\n supportsAllDrives: true,\n }),\n 30000,\n \"List permissions\",\n );\n\n const permissionList = permissions.data.permissions || [];\n\n const permissionData = permissionList.map((p) => ({\n id: p.id,\n role: p.role,\n type: p.type,\n emailAddress: p.emailAddress,\n domain: p.domain,\n displayName: p.displayName,\n }));\n\n const textResponse = `Sharing settings for \"${file.data.name}\":\\n\\n${toToon({ permissions: permissionData })}\\n\\nLink: ${file.data.webViewLink}`;\n\n return structuredResponse(textResponse, {\n fileName: file.data.name,\n webViewLink: file.data.webViewLink,\n permissions: permissionData,\n });\n}\n\n// -----------------------------------------------------------------------------\n// REVISION HANDLERS\n// -----------------------------------------------------------------------------\n\nexport async function handleListRevisions(\n drive: drive_v3.Drive,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(ListRevisionsSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Get file name\n const file = await withTimeout(\n drive.files.get({\n fileId: data.fileId,\n fields: \"name, mimeType\",\n supportsAllDrives: true,\n }),\n 30000,\n \"Get file info\",\n );\n\n // Check if file supports revisions (Google Workspace files use different versioning)\n if (file.data.mimeType?.startsWith(\"application/vnd.google-apps\")) {\n return errorResponse(\n `Google Workspace files (${file.data.mimeType}) do not support revision history through this API. ` +\n `Use the Google Docs/Sheets/Slides UI to view version history.`,\n );\n }\n\n const revisions = await withTimeout(\n drive.revisions.list({\n fileId: data.fileId,\n pageSize: data.pageSize || 100,\n fields: \"revisions(id, modifiedTime, lastModifyingUser, size, keepForever)\",\n }),\n 30000,\n \"List revisions\",\n );\n\n const revisionList = revisions.data.revisions || [];\n\n if (revisionList.length === 0) {\n return successResponse(`No revisions found for \"${file.data.name}\".`);\n }\n\n const revisionData = revisionList.map((r) => ({\n id: r.id,\n modifiedTime: r.modifiedTime,\n size: r.size,\n keepForever: r.keepForever,\n lastModifyingUser: r.lastModifyingUser\n ? {\n displayName: r.lastModifyingUser.displayName,\n emailAddress: r.lastModifyingUser.emailAddress,\n }\n : undefined,\n }));\n\n const textResponse = `Revisions for \"${file.data.name}\" (${revisionList.length} found):\\n\\n${toToon({ revisions: revisionData })}`;\n\n return structuredResponse(textResponse, {\n fileName: file.data.name,\n revisions: revisionData,\n });\n}\n\nexport async function handleRestoreRevision(\n drive: drive_v3.Drive,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(RestoreRevisionSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Get file metadata\n const file = await drive.files.get({\n fileId: data.fileId,\n fields: \"name, mimeType\",\n supportsAllDrives: true,\n });\n\n // Check if file supports revisions\n if (file.data.mimeType?.startsWith(\"application/vnd.google-apps\")) {\n return errorResponse(\n `Google Workspace files cannot be restored through this API. ` +\n `Use the Google Docs/Sheets/Slides UI to restore previous versions.`,\n );\n }\n\n // Get revision content\n const revisionContent = await drive.revisions.get(\n { fileId: data.fileId, revisionId: data.revisionId, alt: \"media\" },\n { responseType: \"arraybuffer\" },\n );\n\n // Update file with revision content\n const { Readable } = await import(\"stream\");\n const stream = Readable.from(Buffer.from(revisionContent.data as ArrayBuffer));\n\n await drive.files.update({\n fileId: data.fileId,\n media: {\n mimeType: file.data.mimeType || \"application/octet-stream\",\n body: stream,\n },\n supportsAllDrives: true,\n });\n\n log(\"Revision restored successfully\", {\n fileId: data.fileId,\n revisionId: data.revisionId,\n });\n return successResponse(`Restored \"${file.data.name}\" to revision ${data.revisionId}`);\n}\n\n// -----------------------------------------------------------------------------\n// BINARY FILE HANDLERS\n// -----------------------------------------------------------------------------\n\nconst COMMON_MIME_TYPES: Record<string, string> = {\n pdf: \"application/pdf\",\n png: \"image/png\",\n jpg: \"image/jpeg\",\n jpeg: \"image/jpeg\",\n gif: \"image/gif\",\n webp: \"image/webp\",\n svg: \"image/svg+xml\",\n mp4: \"video/mp4\",\n mp3: \"audio/mpeg\",\n zip: \"application/zip\",\n json: \"application/json\",\n xml: \"application/xml\",\n html: \"text/html\",\n css: \"text/css\",\n js: \"application/javascript\",\n};\n\nexport async function handleDownloadFile(\n drive: drive_v3.Drive,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(DownloadFileSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Get file metadata\n const file = await drive.files.get({\n fileId: data.fileId,\n fields: \"name, mimeType, size\",\n supportsAllDrives: true,\n });\n\n const mimeType = file.data.mimeType || \"\";\n const fileName = file.data.name || \"download\";\n\n // Reject Google Workspace files\n if (mimeType.startsWith(\"application/vnd.google-apps\")) {\n return errorResponse(\n `\"${fileName}\" is a Google Workspace file (${mimeType}). ` +\n `Use exportFile instead to convert it to a downloadable format.`,\n );\n }\n\n // Download file content\n const response = await drive.files.get(\n { fileId: data.fileId, alt: \"media\", supportsAllDrives: true },\n { responseType: \"arraybuffer\" },\n );\n\n const buffer = Buffer.from(response.data as ArrayBuffer);\n\n // If outputPath provided, save to file\n if (data.outputPath) {\n const fs = await import(\"fs/promises\");\n const path = await import(\"path\");\n\n const fullPath = path.join(data.outputPath, fileName);\n await fs.writeFile(fullPath, buffer);\n\n log(\"File downloaded successfully\", {\n fileId: data.fileId,\n outputPath: fullPath,\n });\n return successResponse(\n `Downloaded \"${fileName}\" to: ${fullPath}\\n` +\n `Size: ${buffer.length} bytes\\n` +\n `Type: ${mimeType}`,\n );\n }\n\n // Otherwise return base64\n const base64Content = buffer.toString(\"base64\");\n\n log(\"File downloaded successfully\", {\n fileId: data.fileId,\n size: buffer.length,\n });\n return successResponse(\n `Downloaded \"${fileName}\"\\n` +\n `Size: ${buffer.length} bytes\\n` +\n `Type: ${mimeType}\\n\\n` +\n `Base64 content:\\n${base64Content}`,\n );\n}\n\nexport async function handleUploadFile(\n drive: drive_v3.Drive,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(UploadFileSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Require either sourcePath or base64Content\n if (!data.sourcePath && !data.base64Content) {\n return errorResponse(\"Either sourcePath or base64Content is required\");\n }\n\n // Auto-detect mimeType from extension if not provided\n let mimeType = data.mimeType;\n if (!mimeType) {\n const ext = data.name.split(\".\").pop()?.toLowerCase() || \"\";\n mimeType = COMMON_MIME_TYPES[ext] || \"application/octet-stream\";\n }\n\n // Resolve folder ID (supports both folderId and folderPath)\n const folderId = await resolveOptionalFolderPath(drive, data.folderId, data.folderPath);\n\n // Check if file already exists\n const existingFileId = await checkFileExists(drive, data.name, folderId);\n if (existingFileId) {\n return errorResponse(\n `A file named \"${data.name}\" already exists in this location. ` +\n `Existing file ID: ${existingFileId}`,\n );\n }\n\n // Prepare content stream\n let mediaBody: NodeJS.ReadableStream;\n if (data.sourcePath) {\n const fs = await import(\"fs\");\n mediaBody = fs.createReadStream(data.sourcePath);\n } else {\n const { Readable } = await import(\"stream\");\n const buffer = Buffer.from(data.base64Content!, \"base64\");\n mediaBody = Readable.from(buffer);\n }\n\n // Upload file\n const file = await drive.files.create({\n requestBody: {\n name: data.name,\n parents: [folderId],\n },\n media: {\n mimeType,\n body: mediaBody,\n },\n fields: \"id, name, webViewLink\",\n supportsAllDrives: true,\n });\n\n log(\"File uploaded successfully\", {\n fileId: file.data.id,\n name: file.data.name,\n });\n return successResponse(\n `Uploaded file: ${file.data.name}\\n` +\n `ID: ${file.data.id}\\n` +\n `Link: ${file.data.webViewLink}`,\n );\n}\n\n// -----------------------------------------------------------------------------\n// METADATA HANDLERS\n// -----------------------------------------------------------------------------\n\nexport async function handleGetStorageQuota(\n drive: drive_v3.Drive,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(GetStorageQuotaSchema, args);\n if (!validation.success) return validation.response;\n\n const about = await withTimeout(\n drive.about.get({\n fields: \"storageQuota, user\",\n }),\n 30000,\n \"Get storage quota\",\n );\n\n const quota = about.data.storageQuota;\n const user = about.data.user;\n\n if (!quota) {\n return errorResponse(\"Unable to retrieve storage quota information\");\n }\n\n const limit = quota.limit ? formatBytes(quota.limit) : \"Unlimited\";\n const usage = formatBytes(quota.usage);\n const usageInDrive = formatBytes(quota.usageInDrive);\n const usageInTrash = formatBytes(quota.usageInDriveTrash);\n\n let available = \"Unlimited\";\n if (quota.limit && quota.usage) {\n const availableBytes = parseInt(quota.limit) - parseInt(quota.usage);\n available = formatBytes(String(availableBytes));\n }\n\n const textResponse =\n `Google Drive Storage Quota\\n` +\n `User: ${user?.emailAddress || \"Unknown\"}\\n\\n` +\n `Total limit: ${limit}\\n` +\n `Total usage: ${usage}\\n` +\n `Usage in Drive: ${usageInDrive}\\n` +\n `Usage in Trash: ${usageInTrash}\\n` +\n `Available: ${available}`;\n\n return structuredResponse(textResponse, {\n user: user\n ? {\n displayName: user.displayName,\n emailAddress: user.emailAddress,\n }\n : undefined,\n storageQuota: {\n limit: quota.limit,\n usage: quota.usage,\n usageInDrive: quota.usageInDrive,\n usageInDriveTrash: quota.usageInDriveTrash,\n },\n });\n}\n\nexport async function handleStarFile(drive: drive_v3.Drive, args: unknown): Promise<ToolResponse> {\n const validation = validateArgs(StarFileSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Get file name\n const file = await drive.files.get({\n fileId: data.fileId,\n fields: \"name\",\n supportsAllDrives: true,\n });\n\n // Update starred status\n await drive.files.update({\n fileId: data.fileId,\n requestBody: { starred: data.starred },\n supportsAllDrives: true,\n });\n\n const action = data.starred ? \"starred\" : \"unstarred\";\n log(`File ${action} successfully`, { fileId: data.fileId });\n return successResponse(`Successfully ${action} \"${file.data.name}\"`);\n}\n\n// -----------------------------------------------------------------------------\n// FILE PATH RESOLUTION - HELPERS\n// -----------------------------------------------------------------------------\n\ninterface PathSegmentQuery {\n folderId: string;\n segmentName: string;\n isLastSegment: boolean;\n targetType?: \"file\" | \"folder\" | \"any\";\n}\n\nfunction buildPathSegmentQuery(params: PathSegmentQuery): string {\n const { folderId, segmentName, isLastSegment, targetType } = params;\n const escapedName = escapeQueryString(segmentName);\n\n let query = combineQueries(\n `'${folderId}' in parents`,\n `name = '${escapedName}'`,\n \"trashed = false\",\n );\n\n if (isLastSegment && targetType !== \"any\") {\n if (targetType === \"folder\") {\n query += ` and mimeType = '${FOLDER_MIME_TYPE}'`;\n } else if (targetType === \"file\") {\n query += ` and mimeType != '${FOLDER_MIME_TYPE}'`;\n }\n } else if (!isLastSegment) {\n query += ` and mimeType = '${FOLDER_MIME_TYPE}'`;\n }\n\n return query;\n}\n\nasync function buildNotFoundError(\n drive: drive_v3.Drive,\n segment: string,\n folderId: string,\n resolvedPath: string[],\n): Promise<string> {\n const pathSoFar = \"/\" + resolvedPath.join(\"/\");\n const searchedIn =\n resolvedPath.length > 0 ? `\"${resolvedPath[resolvedPath.length - 1]}\"` : \"root\";\n\n const contentsResponse = await drive.files.list({\n q: `'${folderId}' in parents and trashed = false`,\n fields: \"files(name, mimeType)\",\n pageSize: 20,\n includeItemsFromAllDrives: true,\n supportsAllDrives: true,\n });\n\n const contents = (contentsResponse.data.files || [])\n .map((f) => (f.mimeType === FOLDER_MIME_TYPE ? `\uD83D\uDCC1 ${f.name}` : `\uD83D\uDCC4 ${f.name}`))\n .slice(0, 10);\n\n const contentsStr =\n contents.length > 0\n ? `\\nContents of ${searchedIn}: ${contents.join(\", \")}${contents.length >= 10 ? \"...\" : \"\"}`\n : `\\n${searchedIn} appears to be empty.`;\n\n return `Path segment \"${segment}\" not found at \"${pathSoFar || \"/\"}\".${contentsStr}`;\n}\n\ninterface ResolvedFileInfo {\n id: string;\n name: string;\n mimeType: string | null | undefined;\n modifiedTime: string | null | undefined;\n}\n\nfunction buildResolvedResponse(\n file: ResolvedFileInfo,\n originalPath: string,\n resolvedPath: string[],\n): ToolResponse {\n const typeLabel = file.mimeType === FOLDER_MIME_TYPE ? \"folder\" : \"file\";\n return structuredResponse(`Resolved \"${originalPath}\" to ${typeLabel} \"${file.name}\"`, {\n id: file.id,\n name: file.name,\n path: \"/\" + resolvedPath.join(\"/\"),\n mimeType: file.mimeType,\n modifiedTime: file.modifiedTime,\n });\n}\n\nasync function handleMultipleMatches(\n files: drive_v3.Schema$File[],\n segment: string,\n resolvedPath: string[],\n context: HandlerContext | undefined,\n): Promise<{ selectedFile?: drive_v3.Schema$File; error?: string }> {\n if (!context?.server) {\n const message = formatDisambiguationOptions(\n files.map((f) => ({\n id: f.id!,\n name: f.name!,\n mimeType: f.mimeType || undefined,\n modifiedTime: f.modifiedTime,\n })),\n `Multiple items named \"${segment}\" found at \"/${resolvedPath.join(\"/\")}\".`,\n );\n return { error: message };\n }\n\n const fileOptions = files.map((f) => ({\n id: f.id!,\n name: f.name!,\n mimeType: f.mimeType || undefined,\n modifiedTime: f.modifiedTime || undefined,\n path: \"/\" + [...resolvedPath, f.name!].join(\"/\"),\n }));\n\n const result = await elicitFileSelection(\n context.server,\n fileOptions,\n `Multiple items named \"${segment}\" found at \"/${resolvedPath.join(\"/\")}\". Please select one:`,\n );\n\n if (result.cancelled) return { error: \"File selection cancelled\" };\n if (result.error) return { error: result.error };\n if (result.selectedFileId) {\n const selected = files.find((f) => f.id === result.selectedFileId);\n return { selectedFile: selected };\n }\n return { error: \"No file selected\" };\n}\n\n// -----------------------------------------------------------------------------\n// FILE PATH RESOLUTION\n// -----------------------------------------------------------------------------\n\nexport async function handleResolveFilePath(\n drive: drive_v3.Drive,\n args: unknown,\n context?: HandlerContext,\n): Promise<ToolResponse> {\n const validation = validateArgs(ResolveFilePathSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n if (!data.path || data.path === \"/\") {\n return structuredResponse(\"Resolved to root folder\", {\n id: \"root\",\n name: \"My Drive\",\n path: \"/\",\n mimeType: FOLDER_MIME_TYPE,\n modifiedTime: null,\n });\n }\n\n const parts = data.path.replace(/^\\/+|\\/+$/g, \"\").split(\"/\");\n let currentFolderId = \"root\";\n const resolvedPath: string[] = [];\n\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i];\n if (!part) continue;\n\n const isLastPart = i === parts.length - 1;\n const query = buildPathSegmentQuery({\n folderId: currentFolderId,\n segmentName: part,\n isLastSegment: isLastPart,\n targetType: data.type,\n });\n\n const response = await drive.files.list({\n q: query,\n fields: \"files(id, name, mimeType, modifiedTime)\",\n pageSize: 10,\n includeItemsFromAllDrives: true,\n supportsAllDrives: true,\n });\n\n const files = response.data.files || [];\n\n if (files.length === 0) {\n const errorMsg = await buildNotFoundError(drive, part, currentFolderId, resolvedPath);\n return errorResponse(errorMsg);\n }\n\n if (files.length > 1) {\n const result = await handleMultipleMatches(files, part, resolvedPath, context);\n if (result.error) return errorResponse(result.error);\n if (result.selectedFile) {\n resolvedPath.push(result.selectedFile.name!);\n if (isLastPart) {\n log(\"Path resolved via elicitation\", { path: data.path, fileId: result.selectedFile.id });\n return buildResolvedResponse(\n {\n id: result.selectedFile.id!,\n name: result.selectedFile.name!,\n mimeType: result.selectedFile.mimeType,\n modifiedTime: result.selectedFile.modifiedTime,\n },\n data.path,\n resolvedPath,\n );\n }\n currentFolderId = result.selectedFile.id!;\n continue;\n }\n }\n\n const file = files[0];\n resolvedPath.push(file.name!);\n\n if (isLastPart) {\n log(\"Path resolved successfully\", { path: data.path, fileId: file.id });\n return buildResolvedResponse(\n {\n id: file.id!,\n name: file.name!,\n mimeType: file.mimeType,\n modifiedTime: file.modifiedTime,\n },\n data.path,\n resolvedPath,\n );\n }\n\n currentFolderId = file.id!;\n }\n\n return errorResponse(\"Unable to resolve path\");\n}\n\n// -----------------------------------------------------------------------------\n// BATCH OPERATIONS\n// -----------------------------------------------------------------------------\n\nexport async function handleBatchDelete(\n drive: drive_v3.Drive,\n args: unknown,\n context?: HandlerContext,\n): Promise<ToolResponse> {\n const validation = validateArgs(BatchDeleteSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n const { success: deleted, failed } = await processBatchOperation(\n data.fileIds,\n async (fileId) => {\n const file = await drive.files.get({\n fileId,\n fields: \"name\",\n supportsAllDrives: true,\n });\n\n await drive.files.update({\n fileId,\n requestBody: { trashed: true },\n supportsAllDrives: true,\n });\n\n return { fileId, name: file.data.name };\n },\n context,\n { operationName: \"Deleting files\" },\n );\n\n const summary = `Batch delete: ${deleted.length} succeeded, ${failed.length} failed`;\n log(summary, { deleted: deleted.length, failed: failed.length });\n\n return structuredResponse(\n summary +\n (deleted.length > 0\n ? `\\n\\nDeleted: ${deleted.map((d) => d.name || d.fileId).join(\", \")}`\n : \"\") +\n (failed.length > 0\n ? `\\n\\nFailed: ${failed.map((f) => `${f.id}: ${f.error}`).join(\", \")}`\n : \"\"),\n { deleted, failed },\n );\n}\n\nexport async function handleBatchMove(\n drive: drive_v3.Drive,\n args: unknown,\n context?: HandlerContext,\n): Promise<ToolResponse> {\n const validation = validateArgs(BatchMoveSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Resolve destination folder (supports both ID and path)\n const destinationFolderId = await resolveOptionalFolderPath(\n drive,\n data.destinationFolderId,\n data.destinationPath,\n );\n\n // Get destination folder name for better reporting\n let destName = \"root\";\n if (destinationFolderId !== \"root\") {\n try {\n const destFolder = await withRetry(\n () =>\n drive.files.get({\n fileId: destinationFolderId,\n fields: \"name\",\n supportsAllDrives: true,\n }),\n { operationName: \"getDestinationFolder\" },\n );\n destName = destFolder.data.name || destinationFolderId;\n } catch {\n return errorResponse(`Destination folder not found: ${destinationFolderId}`);\n }\n }\n\n const { success: moved, failed } = await processBatchOperation(\n data.fileIds,\n async (fileId) => {\n const file = await drive.files.get({\n fileId,\n fields: \"name, parents\",\n supportsAllDrives: true,\n });\n\n const previousParents = (file.data.parents || []).join(\",\");\n\n await drive.files.update({\n fileId,\n addParents: destinationFolderId,\n removeParents: previousParents,\n supportsAllDrives: true,\n });\n\n return { fileId, name: file.data.name };\n },\n context,\n { operationName: `Moving files to \"${destName}\"` },\n );\n\n const summary = `Batch move to \"${destName}\": ${moved.length} succeeded, ${failed.length} failed`;\n log(summary, { moved: moved.length, failed: failed.length });\n\n return structuredResponse(\n summary +\n (moved.length > 0 ? `\\n\\nMoved: ${moved.map((m) => m.name || m.fileId).join(\", \")}` : \"\") +\n (failed.length > 0\n ? `\\n\\nFailed: ${failed.map((f) => `${f.id}: ${f.error}`).join(\", \")}`\n : \"\"),\n {\n moved,\n failed,\n destinationFolder: { id: destinationFolderId, name: destName },\n },\n );\n}\n\nexport async function handleBatchShare(\n drive: drive_v3.Drive,\n args: unknown,\n context?: HandlerContext,\n): Promise<ToolResponse> {\n const validation = validateArgs(BatchShareSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n const { success: shared, failed } = await processBatchOperation(\n data.fileIds,\n async (fileId) => {\n const file = await drive.files.get({\n fileId,\n fields: \"name\",\n supportsAllDrives: true,\n });\n\n await drive.permissions.create({\n fileId,\n requestBody: {\n role: data.role,\n type: \"user\",\n emailAddress: data.email,\n },\n sendNotificationEmail: data.sendNotification,\n supportsAllDrives: true,\n });\n\n return { fileId, name: file.data.name };\n },\n context,\n { operationName: `Sharing files with ${data.email}` },\n );\n\n const summary = `Batch share with ${data.email} (${data.role}): ${shared.length} succeeded, ${failed.length} failed`;\n log(summary, { shared: shared.length, failed: failed.length });\n\n return structuredResponse(\n summary +\n (shared.length > 0 ? `\\n\\nShared: ${shared.map((s) => s.name || s.fileId).join(\", \")}` : \"\") +\n (failed.length > 0\n ? `\\n\\nFailed: ${failed.map((f) => `${f.id}: ${f.error}`).join(\", \")}`\n : \"\"),\n { shared, failed, shareDetails: { email: data.email, role: data.role } },\n );\n}\n\nexport async function handleBatchRestore(\n drive: drive_v3.Drive,\n args: unknown,\n context?: HandlerContext,\n): Promise<ToolResponse> {\n const validation = validateArgs(BatchRestoreSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n const { success: restored, failed } = await processBatchOperation(\n data.fileIds,\n async (fileId) => {\n const file = await drive.files.get({\n fileId,\n fields: \"name, trashed\",\n supportsAllDrives: true,\n });\n\n if (!file.data.trashed) {\n throw new Error(`File \"${file.data.name}\" is not in trash`);\n }\n\n await drive.files.update({\n fileId,\n requestBody: { trashed: false },\n supportsAllDrives: true,\n });\n\n return { fileId, name: file.data.name };\n },\n context,\n { operationName: \"Restoring files from trash\" },\n );\n\n const summary = `Batch restore: ${restored.length} succeeded, ${failed.length} failed`;\n log(summary, { restored: restored.length, failed: failed.length });\n\n return structuredResponse(\n summary +\n (restored.length > 0\n ? `\\n\\nRestored: ${restored.map((r) => r.name || r.fileId).join(\", \")}`\n : \"\") +\n (failed.length > 0\n ? `\\n\\nFailed: ${failed.map((f) => `${f.id}: ${f.error}`).join(\", \")}`\n : \"\"),\n { restored, failed },\n );\n}\n\n// -----------------------------------------------------------------------------\n// PERMISSION MANAGEMENT\n// -----------------------------------------------------------------------------\n\nexport async function handleRemovePermission(\n drive: drive_v3.Drive,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(RemovePermissionSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Get file name for reporting\n const file = await drive.files.get({\n fileId: data.fileId,\n fields: \"name\",\n supportsAllDrives: true,\n });\n\n let permissionIdToRemove = data.permissionId;\n\n // If email provided, look up the permission ID\n if (data.email && !permissionIdToRemove) {\n const permissions = await drive.permissions.list({\n fileId: data.fileId,\n fields: \"permissions(id, emailAddress, role)\",\n supportsAllDrives: true,\n });\n\n const permission = (permissions.data.permissions || []).find(\n (p) => p.emailAddress?.toLowerCase() === data.email!.toLowerCase(),\n );\n\n if (!permission) {\n // List current permissions for context\n const currentPerms = (permissions.data.permissions || [])\n .map((p) => `${p.emailAddress || \"anonymous\"} (${p.role})`)\n .join(\", \");\n\n return errorResponse(\n `No permission found for email \"${data.email}\" on file \"${file.data.name}\". ` +\n `Current permissions: ${currentPerms || \"none\"}`,\n );\n }\n\n // Check if this is the owner\n if (permission.role === \"owner\") {\n return errorResponse(\n `Cannot remove owner permission for \"${data.email}\". ` +\n `Transfer ownership first if you want to remove this user's access.`,\n );\n }\n\n permissionIdToRemove = permission.id!;\n }\n\n // Check if trying to remove owner by permissionId\n if (permissionIdToRemove) {\n const permDetails = await drive.permissions.get({\n fileId: data.fileId,\n permissionId: permissionIdToRemove,\n fields: \"role, emailAddress\",\n supportsAllDrives: true,\n });\n\n if (permDetails.data.role === \"owner\") {\n return errorResponse(\n `Cannot remove owner permission (${permDetails.data.emailAddress}). ` +\n `Transfer ownership first if you want to remove this user's access.`,\n );\n }\n }\n\n await drive.permissions.delete({\n fileId: data.fileId,\n permissionId: permissionIdToRemove!,\n supportsAllDrives: true,\n });\n\n log(\"Permission removed successfully\", {\n fileId: data.fileId,\n permissionId: permissionIdToRemove,\n });\n return successResponse(\n `Removed permission from \"${file.data.name}\"` +\n (data.email ? ` for ${data.email}` : ` (permission ID: ${permissionIdToRemove})`),\n );\n}\n\n// -----------------------------------------------------------------------------\n// TRASH MANAGEMENT\n// -----------------------------------------------------------------------------\n\nexport async function handleListTrash(drive: drive_v3.Drive, args: unknown): Promise<ToolResponse> {\n const validation = validateArgs(ListTrashSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n const response = await withTimeout(\n drive.files.list({\n q: \"trashed = true\",\n pageSize: data.pageSize,\n pageToken: data.pageToken,\n fields: \"nextPageToken, files(id, name, mimeType, modifiedTime, size, trashedTime)\",\n includeItemsFromAllDrives: true,\n supportsAllDrives: true,\n }),\n 30000,\n \"List trash\",\n );\n\n const files = response.data.files || [];\n\n if (files.length === 0) {\n return structuredResponse(\"Trash is empty\", {\n files: [],\n nextPageToken: null,\n });\n }\n\n const fileData = files.map((f) => ({\n id: f.id,\n name: f.name,\n mimeType: f.mimeType,\n size: f.size,\n trashedTime: f.trashedTime,\n }));\n\n const textResponse =\n `Trash contents (${files.length} items):\\n\\n${toToon({ files: fileData })}` +\n (response.data.nextPageToken\n ? \"\\n\\n(More items available - use nextPageToken to continue)\"\n : \"\");\n\n return structuredResponse(textResponse, {\n files: fileData,\n nextPageToken: response.data.nextPageToken || null,\n });\n}\n\nexport async function handleRestoreFromTrash(\n drive: drive_v3.Drive,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(RestoreFromTrashSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Get file info\n const file = await drive.files.get({\n fileId: data.fileId,\n fields: \"name, trashed, parents\",\n supportsAllDrives: true,\n });\n\n if (!file.data.trashed) {\n return errorResponse(`File \"${file.data.name}\" is not in trash`, {\n code: \"INVALID_INPUT\",\n context: { fileId: data.fileId },\n });\n }\n\n // First, restore from trash\n await drive.files.update({\n fileId: data.fileId,\n requestBody: { trashed: false },\n supportsAllDrives: true,\n });\n\n // If destination is specified, move to that folder\n let destinationInfo: { id: string; name: string } | undefined;\n if (data.destinationFolderId || data.destinationPath) {\n const destinationFolderId = await resolveOptionalFolderPath(\n drive,\n data.destinationFolderId,\n data.destinationPath,\n );\n\n // Get destination folder name\n let destName = \"root\";\n if (destinationFolderId !== \"root\") {\n const destFolder = await drive.files.get({\n fileId: destinationFolderId,\n fields: \"name\",\n supportsAllDrives: true,\n });\n destName = destFolder.data.name || destinationFolderId;\n }\n\n // Move to destination\n const currentParents = file.data.parents?.join(\",\") || \"\";\n await drive.files.update({\n fileId: data.fileId,\n addParents: destinationFolderId,\n removeParents: currentParents,\n supportsAllDrives: true,\n });\n\n destinationInfo = { id: destinationFolderId, name: destName };\n log(\"File restored from trash and moved\", {\n fileId: data.fileId,\n destinationFolderId,\n });\n return structuredResponse(\n `Restored \"${file.data.name}\" from trash and moved to \"${destName}\"`,\n {\n fileName: file.data.name,\n restored: true,\n destinationFolder: destinationInfo,\n },\n );\n }\n\n log(\"File restored from trash\", { fileId: data.fileId });\n return structuredResponse(`Restored \"${file.data.name}\" from trash`, {\n fileName: file.data.name,\n restored: true,\n });\n}\n\nexport async function handleEmptyTrash(\n drive: drive_v3.Drive,\n args: unknown,\n context?: HandlerContext,\n): Promise<ToolResponse> {\n const validation = validateArgs(EmptyTrashSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Count items in trash first\n const listParams: {\n q: string;\n fields: string;\n pageSize: number;\n driveId?: string;\n corpora?: string;\n } = {\n q: \"trashed = true\",\n fields: \"files(id, name)\",\n pageSize: 1000,\n };\n\n // If driveId is specified, query that shared drive's trash\n if (data.driveId) {\n listParams.driveId = data.driveId;\n listParams.corpora = \"drive\";\n }\n\n const trashContents = await drive.files.list(listParams);\n\n const itemCount = trashContents.data.files?.length || 0;\n\n if (itemCount === 0) {\n return successResponse(\n data.driveId ? \"Shared drive trash is already empty\" : \"Trash is already empty\",\n );\n }\n\n // Use elicitation for confirmation if context available\n if (context?.server) {\n const sampleFiles = (trashContents.data.files || [])\n .slice(0, 5)\n .map((f) => f.name)\n .join(\", \");\n const moreText = itemCount > 5 ? ` and ${itemCount - 5} more` : \"\";\n\n const confirmResult = await elicitConfirmation(\n context.server,\n `Permanently delete ${itemCount} item(s) from ${data.driveId ? \"shared drive \" : \"\"}trash?`,\n `This action cannot be undone. Files: ${sampleFiles}${moreText}`,\n );\n\n if (confirmResult.cancelled) {\n return errorResponse(\"Empty trash operation cancelled\");\n }\n\n if (!confirmResult.confirmed) {\n return errorResponse(\n `Empty trash requires confirmation. ${itemCount} item(s) will be permanently deleted. ` +\n `Files include: ${sampleFiles}${moreText}`,\n );\n }\n }\n\n // Empty trash - pass driveId if specified for shared drives\n await drive.files.emptyTrash(data.driveId ? { driveId: data.driveId } : {});\n\n log(\"Trash emptied\", { itemCount, driveId: data.driveId });\n return successResponse(\n data.driveId\n ? `Permanently deleted ${itemCount} item(s) from shared drive trash`\n : `Permanently deleted ${itemCount} item(s) from trash`,\n );\n}\n\n// -----------------------------------------------------------------------------\n// FOLDER TREE DISCOVERY\n// -----------------------------------------------------------------------------\n\ninterface FolderTreeNode {\n id: string;\n name: string;\n type: \"folder\" | \"file\";\n mimeType?: string;\n children?: FolderTreeNode[];\n truncated?: boolean;\n}\n\nasync function buildFolderTree(\n drive: drive_v3.Drive,\n folderId: string,\n folderName: string,\n currentDepth: number,\n maxDepth: number,\n): Promise<FolderTreeNode> {\n const node: FolderTreeNode = {\n id: folderId,\n name: folderName,\n type: \"folder\",\n };\n\n if (currentDepth >= maxDepth) {\n return node;\n }\n\n // List contents of this folder\n const response = await drive.files.list({\n q: `'${folderId}' in parents and trashed = false`,\n fields: \"files(id, name, mimeType)\",\n pageSize: 100,\n orderBy: \"folder,name\",\n includeItemsFromAllDrives: true,\n supportsAllDrives: true,\n });\n\n const files = response.data.files || [];\n const children: FolderTreeNode[] = [];\n\n // Check if results were truncated (100 is pageSize limit)\n const truncated = files.length >= 100;\n\n for (const file of files) {\n if (file.mimeType === FOLDER_MIME_TYPE) {\n // Recursively build tree for subfolders\n const childNode = await buildFolderTree(\n drive,\n file.id!,\n file.name!,\n currentDepth + 1,\n maxDepth,\n );\n children.push(childNode);\n } else {\n // Add file node\n children.push({\n id: file.id!,\n name: file.name!,\n type: \"file\",\n mimeType: file.mimeType || undefined,\n });\n }\n }\n\n if (children.length > 0) {\n node.children = children;\n }\n\n if (truncated) {\n node.truncated = true;\n }\n\n return node;\n}\n\nfunction formatTreeAsText(\n node: FolderTreeNode,\n indent: string = \"\",\n isLast: boolean = true,\n): string {\n const prefix = indent + (isLast ? \"\u2514\u2500\u2500 \" : \"\u251C\u2500\u2500 \");\n const icon = node.type === \"folder\" ? \"\uD83D\uDCC1\" : \"\uD83D\uDCC4\";\n const truncatedIndicator = node.truncated ? \" (100+ items, truncated)\" : \"\";\n let result = prefix + icon + \" \" + node.name + truncatedIndicator + \"\\n\";\n\n if (node.children) {\n const childIndent = indent + (isLast ? \" \" : \"\u2502 \");\n node.children.forEach((child, index) => {\n const isLastChild = index === node.children!.length - 1;\n result += formatTreeAsText(child, childIndent, isLastChild);\n });\n }\n\n return result;\n}\n\nexport async function handleGetFolderTree(\n drive: drive_v3.Drive,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(GetFolderTreeSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Resolve folder ID\n const folderId = await resolveOptionalFolderPath(drive, data.folderId, data.folderPath);\n\n // Get folder name\n let folderName = \"My Drive\";\n let folderPath = \"/\";\n\n if (folderId !== \"root\") {\n const folder = await drive.files.get({\n fileId: folderId,\n fields: \"name\",\n supportsAllDrives: true,\n });\n folderName = folder.data.name || folderId;\n folderPath = data.folderPath || `/${folderName}`;\n }\n\n // Build tree structure\n const tree = await buildFolderTree(drive, folderId, folderName, 0, data.depth || 2);\n\n // Format as text\n const truncatedIndicator = tree.truncated ? \" (100+ items, truncated)\" : \"\";\n const treeText =\n \"\uD83D\uDCC1 \" +\n folderName +\n truncatedIndicator +\n \"\\n\" +\n (tree.children\n ? tree.children\n .map((child, index) => formatTreeAsText(child, \"\", index === tree.children!.length - 1))\n .join(\"\")\n : \"(empty)\");\n\n return structuredResponse(treeText, {\n id: folderId,\n name: folderName,\n path: folderPath,\n children: tree.children || [],\n truncated: tree.truncated,\n });\n}\n", "/**\n * Google Drive query building utilities.\n *\n * Google Drive's query syntax requires escaping special characters\n * in query strings. These utilities provide consistent escaping and\n * query construction for searching files and folders.\n */\n\n/**\n * Escape special characters for Google Drive query strings.\n * Escapes backslashes and single quotes which have special meaning in queries.\n */\nexport function escapeQueryString(text: string): string {\n return text.replace(/\\\\/g, \"\\\\\\\\\").replace(/'/g, \"\\\\'\");\n}\n\n/**\n * Build a name query for exact or partial match.\n *\n * @param name - The file/folder name to search for\n * @param exact - If true, uses exact match (=). If false, uses contains.\n * @returns Query string like \"name = 'escaped-name'\" or \"name contains 'escaped-name'\"\n */\nexport function buildNameQuery(name: string, exact = true): string {\n const escaped = escapeQueryString(name);\n return exact ? `name = '${escaped}'` : `name contains '${escaped}'`;\n}\n\n/**\n * Build a parent folder query.\n *\n * @param folderId - The parent folder ID\n * @returns Query string like \"'folderId' in parents\"\n */\nexport function buildParentQuery(folderId: string): string {\n return `'${folderId}' in parents`;\n}\n\n/**\n * Build a full text search query.\n *\n * @param searchText - The text to search for in file contents\n * @returns Query string like \"fullText contains 'escaped-text'\"\n */\nexport function buildFullTextQuery(searchText: string): string {\n const escaped = escapeQueryString(searchText);\n return `fullText contains '${escaped}'`;\n}\n\n/**\n * Build a MIME type filter query.\n *\n * @param mimeType - The MIME type to filter for\n * @returns Query string like \"mimeType = 'application/vnd.google-apps.folder'\"\n */\nexport function buildMimeTypeQuery(mimeType: string): string {\n return `mimeType = '${mimeType}'`;\n}\n\n/**\n * Combine multiple query conditions with AND.\n *\n * @param conditions - Array of query conditions\n * @returns Combined query string with \" and \" between conditions\n */\nexport function combineQueries(...conditions: string[]): string {\n return conditions.filter(Boolean).join(\" and \");\n}\n", "/**\n * Formatting utilities for file sizes and other values.\n */\n\n/**\n * Unit labels for byte formatting.\n */\nconst BYTE_UNITS = [\"B\", \"KB\", \"MB\", \"GB\", \"TB\"] as const;\n\n/**\n * Format bytes into human-readable string.\n *\n * @param bytes - The byte count (string, number, null, or undefined)\n * @param options - Formatting options\n * @param options.precision - Number of decimal places (default: 2)\n * @param options.nullValue - Value to return for null/undefined/NaN input (default: 'N/A')\n * @returns Formatted string like \"1.25 MB\" or \"N/A\"\n */\nexport function formatBytes(\n bytes: string | number | null | undefined,\n options: { precision?: number; nullValue?: string } = {},\n): string {\n const { precision = 2, nullValue = \"N/A\" } = options;\n\n // Handle null/undefined\n if (bytes === null || bytes === undefined) {\n return nullValue;\n }\n\n // Parse to number\n const num = typeof bytes === \"string\" ? parseInt(bytes, 10) : bytes;\n\n // Handle NaN or invalid\n if (isNaN(num)) {\n return nullValue;\n }\n\n // Handle zero\n if (num === 0) {\n return \"0 B\";\n }\n\n // Find appropriate unit\n let unitIndex = 0;\n let value = Math.abs(num);\n\n while (value >= 1024 && unitIndex < BYTE_UNITS.length - 1) {\n value /= 1024;\n unitIndex++;\n }\n\n // Preserve sign\n if (num < 0) {\n value = -value;\n }\n\n // Format with precision, but strip trailing zeros for whole numbers\n const formatted = value.toFixed(precision);\n return `${formatted} ${BYTE_UNITS[unitIndex]}`;\n}\n\n/**\n * Format bytes with a compact style (1 decimal place, B instead of bytes).\n * Useful for condensed displays like tables.\n *\n * @param bytes - The byte count\n * @param nullValue - Value to return for null/undefined input\n * @returns Formatted string like \"1.2 MB\" or \"N/A\"\n */\nexport function formatBytesCompact(\n bytes: string | number | null | undefined,\n nullValue = \"N/A\",\n): string {\n return formatBytes(bytes, { precision: 1, nullValue });\n}\n", "import { z } from \"zod\";\n\nexport const GetFolderTreeSchema = z\n .object({\n folderId: z.string().optional(),\n folderPath: z.string().optional(),\n depth: z.number().min(1).max(5).optional().default(2),\n })\n .refine((data) => !(data.folderId && data.folderPath), {\n message: \"Provide either folderId or folderPath, not both\",\n });\n\nexport type GetFolderTreeInput = z.infer<typeof GetFolderTreeSchema>;\n\nexport const SearchSchema = z.object({\n query: z.string().min(1, \"Search query is required\"),\n searchType: z\n .enum([\"fulltext\", \"name\", \"name_exact\"])\n .optional()\n .default(\"fulltext\")\n .describe(\n \"Search type: 'fulltext' (default, searches content), 'name' (filename contains), 'name_exact' (exact filename match)\",\n ),\n pageSize: z.number().int().min(1).max(100).optional(),\n pageToken: z.string().optional(),\n});\n\nexport const CreateTextFileSchema = z\n .object({\n name: z.string().min(1, \"File name is required\"),\n content: z.string(),\n parentFolderId: z.string().optional(),\n parentPath: z.string().optional(),\n })\n .refine((data) => !(data.parentFolderId && data.parentPath), {\n message: \"Provide either parentFolderId or parentPath, not both\",\n });\n\nexport const UpdateTextFileSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\"),\n content: z.string(),\n name: z.string().optional(),\n});\n\nexport const CreateFolderSchema = z\n .object({\n name: z.string().min(1, \"Folder name is required\"),\n parent: z.string().optional(),\n parentPath: z.string().optional(),\n })\n .refine((data) => !(data.parent && data.parentPath), {\n message: \"Provide either parent (folderId) or parentPath, not both\",\n });\n\nexport const ListFolderSchema = z.object({\n folderId: z.string().optional(),\n pageSize: z.number().int().min(1).max(100).optional(),\n pageToken: z.string().optional(),\n});\n\nexport const DeleteItemSchema = z.object({\n itemId: z.string().min(1, \"Item ID is required\"),\n});\n\nexport const RenameItemSchema = z.object({\n itemId: z.string().min(1, \"Item ID is required\"),\n newName: z.string().min(1, \"New name is required\"),\n});\n\nexport const MoveItemSchema = z\n .object({\n itemId: z.string().min(1, \"Item ID is required\"),\n destinationFolderId: z.string().optional(),\n destinationPath: z.string().optional(),\n })\n .refine((data) => !(data.destinationFolderId && data.destinationPath), {\n message: \"Provide either destinationFolderId or destinationPath, not both\",\n });\n\nexport const CopyFileSchema = z.object({\n sourceFileId: z.string().min(1, \"Source file ID is required\"),\n destinationName: z.string().optional(),\n destinationFolderId: z.string().optional(),\n});\n\nexport const GetFileMetadataSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\"),\n});\n\nexport const ExportFileSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\"),\n format: z.enum([\"pdf\", \"docx\", \"xlsx\", \"pptx\", \"csv\", \"tsv\", \"odt\", \"ods\", \"odp\"]),\n outputPath: z.string().optional(),\n});\n\n// Sharing schemas\nexport const ShareFileSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\"),\n role: z.enum([\"reader\", \"commenter\", \"writer\", \"organizer\"]),\n type: z.enum([\"user\", \"group\", \"domain\", \"anyone\"]),\n emailAddress: z.string().email().optional(),\n domain: z.string().optional(),\n sendNotificationEmail: z.boolean().optional().default(true),\n emailMessage: z.string().optional(),\n});\n\nexport const GetSharingSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\"),\n});\n\n// Revision schemas\nexport const ListRevisionsSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\"),\n pageSize: z.number().int().min(1).max(1000).optional(),\n});\n\nexport const RestoreRevisionSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\"),\n revisionId: z.string().min(1, \"Revision ID is required\"),\n});\n\n// Binary file schemas\nexport const DownloadFileSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\"),\n outputPath: z.string().optional(),\n});\n\nexport const UploadFileSchema = z\n .object({\n name: z.string().min(1, \"File name is required\"),\n sourcePath: z.string().optional(),\n base64Content: z.string().optional(),\n mimeType: z.string().optional(),\n folderId: z.string().optional(),\n folderPath: z.string().optional(),\n })\n .refine((data) => !(data.folderId && data.folderPath), {\n message: \"Provide either folderId or folderPath, not both\",\n });\n\n// Metadata schemas\nexport const GetStorageQuotaSchema = z.object({});\n\nexport const StarFileSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\"),\n starred: z.boolean(),\n});\n\n// File path resolution\nexport const ResolveFilePathSchema = z.object({\n path: z.string().min(1, \"Path is required\"),\n type: z.enum([\"file\", \"folder\", \"any\"]).optional().default(\"any\"),\n});\n\n// Batch operations\nexport const BatchDeleteSchema = z.object({\n fileIds: z\n .array(z.string())\n .min(1, \"At least one file ID required\")\n .max(100, \"Maximum 100 files per batch\"),\n});\n\nexport const BatchRestoreSchema = z.object({\n fileIds: z\n .array(z.string().min(1))\n .min(1, \"At least one file ID required\")\n .max(100, \"Maximum 100 files per batch\"),\n});\n\nexport const BatchMoveSchema = z\n .object({\n fileIds: z\n .array(z.string())\n .min(1, \"At least one file ID required\")\n .max(100, \"Maximum 100 files per batch\"),\n destinationFolderId: z.string().optional(),\n destinationPath: z.string().optional(),\n })\n .refine((data) => data.destinationFolderId || data.destinationPath, {\n message: \"Either destinationFolderId or destinationPath is required\",\n })\n .refine((data) => !(data.destinationFolderId && data.destinationPath), {\n message: \"Provide either destinationFolderId or destinationPath, not both\",\n });\n\nexport const BatchShareSchema = z.object({\n fileIds: z\n .array(z.string())\n .min(1, \"At least one file ID required\")\n .max(100, \"Maximum 100 files per batch\"),\n email: z.string().email(\"Valid email is required\"),\n role: z.enum([\"reader\", \"writer\", \"commenter\"]),\n sendNotification: z.boolean().optional().default(true),\n});\n\n// Permission management\nexport const RemovePermissionSchema = z\n .object({\n fileId: z.string().min(1, \"File ID is required\"),\n permissionId: z.string().optional(),\n email: z.string().email().optional(),\n })\n .refine((data) => data.permissionId || data.email, {\n message: \"Either permissionId or email is required\",\n });\n\n// Trash management\nexport const ListTrashSchema = z.object({\n pageSize: z.number().int().min(1).max(100).optional().default(50),\n pageToken: z.string().optional(),\n});\n\nexport const RestoreFromTrashSchema = z\n .object({\n fileId: z.string().min(1, \"File ID is required\"),\n destinationFolderId: z.string().optional(),\n destinationPath: z.string().optional(),\n })\n .refine((data) => !(data.destinationFolderId && data.destinationPath), {\n message: \"Provide either destinationFolderId or destinationPath, not both\",\n });\n\nexport const EmptyTrashSchema = z.object({\n confirm: z.literal(true, {\n message: \"Must set confirm: true to empty trash\",\n }),\n driveId: z.string().optional(),\n});\n\n// Type exports\nexport type SearchInput = z.infer<typeof SearchSchema>;\nexport type CreateTextFileInput = z.infer<typeof CreateTextFileSchema>;\nexport type UpdateTextFileInput = z.infer<typeof UpdateTextFileSchema>;\nexport type CreateFolderInput = z.infer<typeof CreateFolderSchema>;\nexport type ListFolderInput = z.infer<typeof ListFolderSchema>;\nexport type DeleteItemInput = z.infer<typeof DeleteItemSchema>;\nexport type RenameItemInput = z.infer<typeof RenameItemSchema>;\nexport type MoveItemInput = z.infer<typeof MoveItemSchema>;\nexport type CopyFileInput = z.infer<typeof CopyFileSchema>;\nexport type GetFileMetadataInput = z.infer<typeof GetFileMetadataSchema>;\nexport type ExportFileInput = z.infer<typeof ExportFileSchema>;\nexport type ShareFileInput = z.infer<typeof ShareFileSchema>;\nexport type GetSharingInput = z.infer<typeof GetSharingSchema>;\nexport type ListRevisionsInput = z.infer<typeof ListRevisionsSchema>;\nexport type RestoreRevisionInput = z.infer<typeof RestoreRevisionSchema>;\nexport type DownloadFileInput = z.infer<typeof DownloadFileSchema>;\nexport type UploadFileInput = z.infer<typeof UploadFileSchema>;\nexport type GetStorageQuotaInput = z.infer<typeof GetStorageQuotaSchema>;\nexport type StarFileInput = z.infer<typeof StarFileSchema>;\nexport type ResolveFilePathInput = z.infer<typeof ResolveFilePathSchema>;\nexport type BatchDeleteInput = z.infer<typeof BatchDeleteSchema>;\nexport type BatchRestoreInput = z.infer<typeof BatchRestoreSchema>;\nexport type BatchMoveInput = z.infer<typeof BatchMoveSchema>;\nexport type BatchShareInput = z.infer<typeof BatchShareSchema>;\nexport type RemovePermissionInput = z.infer<typeof RemovePermissionSchema>;\nexport type ListTrashInput = z.infer<typeof ListTrashSchema>;\nexport type RestoreFromTrashInput = z.infer<typeof RestoreFromTrashSchema>;\nexport type EmptyTrashInput = z.infer<typeof EmptyTrashSchema>;\n", "import { z } from \"zod\";\n\nexport const CreateGoogleDocSchema = z\n .object({\n name: z.string().min(1, \"Document name is required\"),\n content: z.string(),\n parentFolderId: z.string().optional(),\n parentPath: z.string().optional(),\n })\n .refine((data) => !(data.parentFolderId && data.parentPath), {\n message: \"Provide either parentFolderId or parentPath, not both\",\n });\n\nexport const UpdateGoogleDocSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n content: z.string(),\n});\n\nexport const GetGoogleDocContentSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n});\n\nexport const AppendToDocSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n text: z.string().min(1, \"Text is required\"),\n insertNewline: z.boolean().optional().default(true),\n});\n\nexport const InsertTextInDocSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n text: z.string().min(1, \"Text is required\"),\n index: z.number().int().min(1, \"Index must be >= 1 (1 = beginning of document content)\"),\n});\n\nexport const DeleteTextInDocSchema = z\n .object({\n documentId: z.string().min(1, \"Document ID is required\"),\n startIndex: z.number().int().min(1, \"Start index must be >= 1\"),\n endIndex: z.number().int().min(2, \"End index must be >= 2\"),\n })\n .refine((data) => data.endIndex > data.startIndex, {\n message: \"endIndex must be greater than startIndex\",\n });\n\nexport const ReplaceTextInDocSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n searchText: z.string().min(1, \"Search text is required\"),\n replaceText: z.string(),\n matchCase: z.boolean().optional().default(true),\n});\n\nexport const FormatGoogleDocRangeSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n startIndex: z.number().min(1, \"Start index must be at least 1\").optional(),\n endIndex: z.number().min(1, \"End index must be at least 1\").optional(),\n\n // Text formatting\n bold: z.boolean().optional(),\n italic: z.boolean().optional(),\n underline: z.boolean().optional(),\n strikethrough: z.boolean().optional(),\n fontSize: z.number().optional(),\n fontFamily: z.string().optional(),\n foregroundColor: z\n .object({\n red: z.number().min(0).max(1).optional(),\n green: z.number().min(0).max(1).optional(),\n blue: z.number().min(0).max(1).optional(),\n })\n .optional(),\n\n // Paragraph formatting\n alignment: z.enum([\"START\", \"CENTER\", \"END\", \"JUSTIFIED\"]).optional(),\n lineSpacing: z.number().optional(),\n spaceAbove: z.number().optional(),\n spaceBelow: z.number().optional(),\n namedStyleType: z\n .enum([\n \"NORMAL_TEXT\",\n \"TITLE\",\n \"SUBTITLE\",\n \"HEADING_1\",\n \"HEADING_2\",\n \"HEADING_3\",\n \"HEADING_4\",\n \"HEADING_5\",\n \"HEADING_6\",\n ])\n .optional(),\n});\n\n// Type exports\nexport type CreateGoogleDocInput = z.infer<typeof CreateGoogleDocSchema>;\nexport type UpdateGoogleDocInput = z.infer<typeof UpdateGoogleDocSchema>;\nexport type GetGoogleDocContentInput = z.infer<typeof GetGoogleDocContentSchema>;\nexport type AppendToDocInput = z.infer<typeof AppendToDocSchema>;\nexport type InsertTextInDocInput = z.infer<typeof InsertTextInDocSchema>;\nexport type DeleteTextInDocInput = z.infer<typeof DeleteTextInDocSchema>;\nexport type ReplaceTextInDocInput = z.infer<typeof ReplaceTextInDocSchema>;\nexport type FormatGoogleDocRangeInput = z.infer<typeof FormatGoogleDocRangeSchema>;\n", "import { z } from \"zod\";\n\n// Unified sheet tabs schema - replaces list/create/delete/rename individual schemas\nexport const SheetTabsSchema = z\n .object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n action: z.enum([\"list\", \"create\", \"delete\", \"rename\"]),\n title: z.string().optional().describe(\"Tab title (for create/delete)\"),\n index: z.number().int().min(0).optional().describe(\"Position for new tab (create only)\"),\n currentTitle: z.string().optional().describe(\"Current title to rename (rename only)\"),\n newTitle: z.string().optional().describe(\"New title (rename only)\"),\n })\n .refine(\n (data) => {\n switch (data.action) {\n case \"list\":\n return true;\n case \"create\":\n case \"delete\":\n return !!data.title;\n case \"rename\":\n return !!(data.currentTitle && data.newTitle);\n default:\n return false;\n }\n },\n {\n message:\n \"Missing required params: create/delete need 'title', rename needs 'currentTitle' and 'newTitle'\",\n },\n );\n\nexport type SheetTabsInput = z.infer<typeof SheetTabsSchema>;\n\nexport const CreateGoogleSheetSchema = z\n .object({\n name: z.string().min(1, \"Sheet name is required\"),\n data: z.array(z.array(z.string())),\n parentFolderId: z.string().optional(),\n parentPath: z.string().optional(),\n valueInputOption: z.enum([\"RAW\", \"USER_ENTERED\"]).optional(),\n })\n .refine((data) => !(data.parentFolderId && data.parentPath), {\n message: \"Provide either parentFolderId or parentPath, not both\",\n });\n\nexport const UpdateGoogleSheetSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n range: z.string().min(1, \"Range is required\"),\n data: z.array(z.array(z.string())),\n valueInputOption: z.enum([\"RAW\", \"USER_ENTERED\"]).optional(),\n});\n\nexport const GetGoogleSheetContentSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n range: z.string().optional(),\n});\n\n// Color schema reused across formatting options\nconst ColorSchema = z.object({\n red: z.number().min(0).max(1).optional(),\n green: z.number().min(0).max(1).optional(),\n blue: z.number().min(0).max(1).optional(),\n});\n\nexport const FormatGoogleSheetCellsSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n range: z.string().min(1, \"Range is required\"),\n // Cell formatting\n backgroundColor: ColorSchema.optional(),\n horizontalAlignment: z.enum([\"LEFT\", \"CENTER\", \"RIGHT\"]).optional(),\n verticalAlignment: z.enum([\"TOP\", \"MIDDLE\", \"BOTTOM\"]).optional(),\n wrapStrategy: z.enum([\"OVERFLOW_CELL\", \"CLIP\", \"WRAP\"]).optional(),\n // Text formatting\n bold: z.boolean().optional(),\n italic: z.boolean().optional(),\n strikethrough: z.boolean().optional(),\n underline: z.boolean().optional(),\n fontSize: z.number().min(1).optional(),\n fontFamily: z.string().optional(),\n foregroundColor: ColorSchema.optional(),\n // Number formatting\n numberFormat: z\n .object({\n pattern: z.string(),\n type: z\n .enum([\"NUMBER\", \"CURRENCY\", \"PERCENT\", \"DATE\", \"TIME\", \"DATE_TIME\", \"SCIENTIFIC\"])\n .optional(),\n })\n .optional(),\n // Border formatting\n borders: z\n .object({\n style: z.enum([\"SOLID\", \"DASHED\", \"DOTTED\", \"DOUBLE\"]),\n width: z.number().min(1).max(3).optional(),\n color: ColorSchema.optional(),\n top: z.boolean().optional(),\n bottom: z.boolean().optional(),\n left: z.boolean().optional(),\n right: z.boolean().optional(),\n innerHorizontal: z.boolean().optional(),\n innerVertical: z.boolean().optional(),\n })\n .optional(),\n});\n\nexport const MergeGoogleSheetCellsSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n range: z.string().min(1, \"Range is required\"),\n mergeType: z.enum([\"MERGE_ALL\", \"MERGE_COLUMNS\", \"MERGE_ROWS\"]),\n});\n\nexport const AddGoogleSheetConditionalFormatSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n range: z.string().min(1, \"Range is required\"),\n condition: z.object({\n type: z.enum([\n \"NUMBER_GREATER\",\n \"NUMBER_LESS\",\n \"TEXT_CONTAINS\",\n \"TEXT_STARTS_WITH\",\n \"TEXT_ENDS_WITH\",\n \"CUSTOM_FORMULA\",\n ]),\n value: z.string(),\n }),\n format: z.object({\n backgroundColor: z\n .object({\n red: z.number().min(0).max(1).optional(),\n green: z.number().min(0).max(1).optional(),\n blue: z.number().min(0).max(1).optional(),\n })\n .optional(),\n textFormat: z\n .object({\n bold: z.boolean().optional(),\n foregroundColor: z\n .object({\n red: z.number().min(0).max(1).optional(),\n green: z.number().min(0).max(1).optional(),\n blue: z.number().min(0).max(1).optional(),\n })\n .optional(),\n })\n .optional(),\n }),\n});\n\n// Type exports\nexport type CreateGoogleSheetInput = z.infer<typeof CreateGoogleSheetSchema>;\nexport type UpdateGoogleSheetInput = z.infer<typeof UpdateGoogleSheetSchema>;\nexport type GetGoogleSheetContentInput = z.infer<typeof GetGoogleSheetContentSchema>;\nexport type FormatGoogleSheetCellsInput = z.infer<typeof FormatGoogleSheetCellsSchema>;\nexport type MergeGoogleSheetCellsInput = z.infer<typeof MergeGoogleSheetCellsSchema>;\nexport type AddGoogleSheetConditionalFormatInput = z.infer<\n typeof AddGoogleSheetConditionalFormatSchema\n>;\n", "import { z } from \"zod\";\n\n// Reusable color schemas\nconst ColorSchema = z.object({\n red: z.number().min(0).max(1).optional(),\n green: z.number().min(0).max(1).optional(),\n blue: z.number().min(0).max(1).optional(),\n});\n\nconst ColorWithAlphaSchema = ColorSchema.extend({\n alpha: z.number().min(0).max(1).optional(),\n});\n\nexport const ListSlidePagesSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n});\n\nexport type ListSlidePagesInput = z.infer<typeof ListSlidePagesSchema>;\n\nexport const CreateGoogleSlidesSchema = z\n .object({\n name: z.string().min(1, \"Presentation name is required\"),\n slides: z\n .array(\n z.object({\n title: z.string(),\n content: z.string(),\n }),\n )\n .min(1, \"At least one slide is required\"),\n parentFolderId: z.string().optional(),\n parentPath: z.string().optional(),\n })\n .refine((data) => !(data.parentFolderId && data.parentPath), {\n message: \"Provide either parentFolderId or parentPath, not both\",\n });\n\nexport const UpdateGoogleSlidesSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n slides: z\n .array(\n z.object({\n title: z.string(),\n content: z.string(),\n }),\n )\n .min(1, \"At least one slide is required\"),\n});\n\nexport const GetGoogleSlidesContentSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n slideIndex: z.number().min(0).optional(),\n});\n\nexport const CreateGoogleSlidesTextBoxSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n pageObjectId: z.string().min(1, \"Page object ID is required\"),\n text: z.string().min(1, \"Text content is required\"),\n x: z.number(),\n y: z.number(),\n width: z.number(),\n height: z.number(),\n fontSize: z.number().optional(),\n bold: z.boolean().optional(),\n italic: z.boolean().optional(),\n});\n\nexport const CreateGoogleSlidesShapeSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n pageObjectId: z.string().min(1, \"Page object ID is required\"),\n shapeType: z.enum([\n \"RECTANGLE\",\n \"ELLIPSE\",\n \"DIAMOND\",\n \"TRIANGLE\",\n \"STAR\",\n \"ROUND_RECTANGLE\",\n \"ARROW\",\n ]),\n x: z.number(),\n y: z.number(),\n width: z.number(),\n height: z.number(),\n backgroundColor: z\n .object({\n red: z.number().min(0).max(1).optional(),\n green: z.number().min(0).max(1).optional(),\n blue: z.number().min(0).max(1).optional(),\n alpha: z.number().min(0).max(1).optional(),\n })\n .optional(),\n});\n\n// Unified speaker notes schema - replaces get/update individual schemas\nexport const SlidesSpeakerNotesSchema = z\n .object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n slideIndex: z.number().min(0, \"Slide index must be non-negative\"),\n action: z.enum([\"get\", \"update\"]),\n notes: z.string().optional().describe(\"Notes content (required for update)\"),\n })\n .refine(\n (data) => {\n if (data.action === \"update\") return data.notes !== undefined;\n return true;\n },\n { message: \"notes is required for update action\" },\n );\n\nexport type SlidesSpeakerNotesInput = z.infer<typeof SlidesSpeakerNotesSchema>;\n\n// Focused text formatting schema\nexport const FormatSlidesTextSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n objectId: z.string().min(1, \"Object ID is required\"),\n\n // Text range (optional - defaults to all text)\n startIndex: z.number().min(0).optional(),\n endIndex: z.number().min(0).optional(),\n\n // Character formatting\n bold: z.boolean().optional(),\n italic: z.boolean().optional(),\n underline: z.boolean().optional(),\n strikethrough: z.boolean().optional(),\n fontSize: z.number().optional(),\n fontFamily: z.string().optional(),\n foregroundColor: ColorSchema.optional(),\n\n // Paragraph formatting\n alignment: z.enum([\"START\", \"CENTER\", \"END\", \"JUSTIFIED\"]).optional(),\n lineSpacing: z.number().optional(),\n bulletStyle: z\n .enum([\"NONE\", \"DISC\", \"ARROW\", \"SQUARE\", \"DIAMOND\", \"STAR\", \"NUMBERED\"])\n .optional(),\n});\n\n// Focused shape styling schema\nexport const FormatSlidesShapeSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n objectId: z.string().min(1, \"Object ID is required\"),\n\n // Shape fill\n backgroundColor: ColorWithAlphaSchema.optional(),\n\n // Outline styling\n outlineColor: ColorSchema.optional(),\n outlineWeight: z.number().optional(),\n outlineDashStyle: z\n .enum([\"SOLID\", \"DOT\", \"DASH\", \"DASH_DOT\", \"LONG_DASH\", \"LONG_DASH_DOT\"])\n .optional(),\n});\n\n// Focused slide background schema\nexport const FormatSlideBackgroundSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n pageObjectIds: z.array(z.string().min(1)).min(1, \"At least one slide ID is required\"),\n backgroundColor: ColorWithAlphaSchema,\n});\n\n// Type exports\nexport type CreateGoogleSlidesInput = z.infer<typeof CreateGoogleSlidesSchema>;\nexport type UpdateGoogleSlidesInput = z.infer<typeof UpdateGoogleSlidesSchema>;\nexport type GetGoogleSlidesContentInput = z.infer<typeof GetGoogleSlidesContentSchema>;\nexport type CreateGoogleSlidesTextBoxInput = z.infer<typeof CreateGoogleSlidesTextBoxSchema>;\nexport type CreateGoogleSlidesShapeInput = z.infer<typeof CreateGoogleSlidesShapeSchema>;\nexport type FormatSlidesTextInput = z.infer<typeof FormatSlidesTextSchema>;\nexport type FormatSlidesShapeInput = z.infer<typeof FormatSlidesShapeSchema>;\nexport type FormatSlideBackgroundInput = z.infer<typeof FormatSlideBackgroundSchema>;\n", "import { z } from \"zod\";\n\n/**\n * Smart file creation that infers type from name/content.\n * Routes to appropriate Google Workspace type based on extension or explicit type.\n */\nexport const CreateFileSchema = z\n .object({\n name: z.string().min(1, \"File name is required\"),\n content: z.union([\n z.string(),\n z.array(z.array(z.string())), // 2D array for sheets\n z.array(\n z.object({\n // Slides array\n title: z.string(),\n content: z.string(),\n }),\n ),\n ]),\n parentFolderId: z.string().optional(),\n parentPath: z.string().optional(),\n type: z.enum([\"doc\", \"sheet\", \"slides\", \"text\"]).optional(),\n })\n .refine((data) => !(data.parentFolderId && data.parentPath), {\n message: \"Provide either parentFolderId or parentPath, not both\",\n });\n\nexport type CreateFileInput = z.infer<typeof CreateFileSchema>;\n\n/**\n * Smart file update that detects file type from ID.\n * Routes to appropriate update handler based on file's mimeType.\n */\nexport const UpdateFileSchema = z\n .object({\n fileId: z.string().optional(),\n filePath: z.string().optional(),\n content: z.union([\n z.string(),\n z.array(z.array(z.string())), // 2D array for sheets\n z.array(\n z.object({\n // Slides array\n title: z.string(),\n content: z.string(),\n }),\n ),\n ]),\n range: z.string().optional(), // For sheets: \"Sheet1!A1:C10\"\n })\n .refine((data) => data.fileId || data.filePath, {\n message: \"Either fileId or filePath must be provided\",\n })\n .refine((data) => !(data.fileId && data.filePath), {\n message: \"Provide either fileId or filePath, not both\",\n });\n\nexport type UpdateFileInput = z.infer<typeof UpdateFileSchema>;\n\n/**\n * Smart content retrieval that detects file type.\n * Returns structured content for Sheets/Slides, text for Docs/text files.\n */\nexport const GetFileContentSchema = z\n .object({\n fileId: z.string().optional(),\n filePath: z.string().optional(),\n range: z.string().optional(), // For sheets: \"Sheet1!A1:C10\"\n })\n .refine((data) => data.fileId || data.filePath, {\n message: \"Either fileId or filePath must be provided\",\n })\n .refine((data) => !(data.fileId && data.filePath), {\n message: \"Provide either fileId or filePath, not both\",\n });\n\nexport type GetFileContentInput = z.infer<typeof GetFileContentSchema>;\n", "import { z } from \"zod\";\n\n// Shared schemas for Calendar\n\n/**\n * EventDateTime - for specifying timed or all-day events.\n * Must have either dateTime (for timed events) or date (for all-day events), not both.\n */\nexport const EventDateTimeSchema = z\n .object({\n dateTime: z\n .string()\n .optional()\n .describe(\"RFC3339 timestamp with timezone offset (e.g., 2024-01-15T09:00:00-05:00)\"),\n date: z\n .string()\n .optional()\n .describe(\"Date for all-day events (YYYY-MM-DD format, e.g., 2024-01-15)\"),\n timeZone: z.string().optional().describe(\"IANA timezone (e.g., America/New_York)\"),\n })\n .refine((data) => data.dateTime || data.date, {\n message: \"Either dateTime or date is required\",\n })\n .refine((data) => !(data.dateTime && data.date), {\n message: \"Cannot have both dateTime and date - use dateTime for timed events, date for all-day\",\n });\n\nexport type EventDateTimeInput = z.infer<typeof EventDateTimeSchema>;\n\n/**\n * Attendee schema for event invites\n */\nexport const AttendeeSchema = z.object({\n email: z.string().email(\"Valid email required\"),\n displayName: z.string().optional(),\n optional: z.boolean().optional().describe(\"Whether attendance is optional\"),\n responseStatus: z\n .enum([\"needsAction\", \"declined\", \"tentative\", \"accepted\"])\n .optional()\n .describe(\"Attendee's response status\"),\n});\n\nexport type AttendeeInput = z.infer<typeof AttendeeSchema>;\n\n/**\n * Reminder schema for event notifications\n */\nexport const ReminderSchema = z.object({\n method: z.enum([\"email\", \"popup\"]).describe(\"Reminder delivery method\"),\n minutes: z.number().min(0).max(40320).describe(\"Minutes before event (max 4 weeks)\"),\n});\n\nexport type ReminderInput = z.infer<typeof ReminderSchema>;\n\n// Tool-specific schemas\n\nexport const ListCalendarsSchema = z.object({\n showHidden: z.boolean().optional().default(false).describe(\"Include hidden calendars\"),\n showDeleted: z.boolean().optional().default(false).describe(\"Include deleted calendars\"),\n});\n\nexport type ListCalendarsInput = z.infer<typeof ListCalendarsSchema>;\n\nexport const ListEventsSchema = z.object({\n calendarId: z\n .string()\n .optional()\n .default(\"primary\")\n .describe(\"Calendar ID (defaults to primary calendar)\"),\n timeMin: z.string().optional().describe(\"Lower bound for event start time (RFC3339 timestamp)\"),\n timeMax: z.string().optional().describe(\"Upper bound for event start time (RFC3339 timestamp)\"),\n query: z.string().optional().describe(\"Free text search terms\"),\n maxResults: z.number().int().min(1).max(2500).optional().default(250).describe(\"Max events\"),\n pageToken: z.string().optional().describe(\"Token for pagination\"),\n singleEvents: z\n .boolean()\n .optional()\n .default(true)\n .describe(\"Expand recurring events into instances\"),\n orderBy: z\n .enum([\"startTime\", \"updated\"])\n .optional()\n .default(\"startTime\")\n .describe(\"Sort order (startTime requires singleEvents=true)\"),\n});\n\nexport type ListEventsInput = z.infer<typeof ListEventsSchema>;\n\nexport const GetEventSchema = z.object({\n calendarId: z.string().optional().default(\"primary\").describe(\"Calendar ID\"),\n eventId: z.string().min(1, \"Event ID is required\"),\n});\n\nexport type GetEventInput = z.infer<typeof GetEventSchema>;\n\nexport const CreateEventSchema = z.object({\n calendarId: z.string().optional().default(\"primary\").describe(\"Calendar ID\"),\n summary: z.string().min(1, \"Event title is required\"),\n description: z.string().optional().describe(\"Event description\"),\n location: z.string().optional().describe(\"Event location\"),\n start: EventDateTimeSchema.describe(\"Event start time\"),\n end: EventDateTimeSchema.describe(\"Event end time\"),\n attendees: z.array(AttendeeSchema).optional().describe(\"List of attendees\"),\n addGoogleMeet: z.boolean().optional().default(false).describe(\"Add Google Meet video conference\"),\n reminders: z.array(ReminderSchema).optional().describe(\"Custom reminders (overrides defaults)\"),\n colorId: z\n .string()\n .optional()\n .describe(\"Event color ID (1-11, see Google Calendar color palette)\"),\n recurrence: z\n .array(z.string())\n .optional()\n .describe(\"RRULE strings for recurring events (e.g., RRULE:FREQ=WEEKLY;COUNT=10)\"),\n sendUpdates: z\n .enum([\"all\", \"externalOnly\", \"none\"])\n .optional()\n .default(\"all\")\n .describe(\"Who to send notifications to\"),\n});\n\nexport type CreateEventInput = z.infer<typeof CreateEventSchema>;\n\nexport const UpdateEventSchema = z.object({\n calendarId: z.string().optional().default(\"primary\").describe(\"Calendar ID\"),\n eventId: z.string().min(1, \"Event ID is required\"),\n summary: z.string().optional().describe(\"Event title\"),\n description: z.string().optional().describe(\"Event description\"),\n location: z.string().optional().describe(\"Event location\"),\n start: EventDateTimeSchema.optional().describe(\"Event start time\"),\n end: EventDateTimeSchema.optional().describe(\"Event end time\"),\n attendees: z.array(AttendeeSchema).optional().describe(\"Replace attendee list\"),\n addGoogleMeet: z.boolean().optional().describe(\"Add Google Meet video conference\"),\n reminders: z.array(ReminderSchema).optional().describe(\"Custom reminders\"),\n colorId: z.string().optional().describe(\"Event color ID (1-11)\"),\n sendUpdates: z\n .enum([\"all\", \"externalOnly\", \"none\"])\n .optional()\n .default(\"all\")\n .describe(\"Who to send notifications to\"),\n});\n\nexport type UpdateEventInput = z.infer<typeof UpdateEventSchema>;\n\nexport const DeleteEventSchema = z.object({\n calendarId: z.string().optional().default(\"primary\").describe(\"Calendar ID\"),\n eventId: z.string().min(1, \"Event ID is required\"),\n sendUpdates: z\n .enum([\"all\", \"externalOnly\", \"none\"])\n .optional()\n .default(\"all\")\n .describe(\"Who to send cancellation notices to\"),\n});\n\nexport type DeleteEventInput = z.infer<typeof DeleteEventSchema>;\n\nexport const FindFreeTimeSchema = z.object({\n calendarIds: z\n .array(z.string())\n .min(1, \"At least one calendar ID required\")\n .max(50, \"Maximum 50 calendars\")\n .describe(\"Calendar IDs to check for availability\"),\n timeMin: z.string().describe(\"Start of search range (RFC3339 timestamp)\"),\n timeMax: z.string().describe(\"End of search range (RFC3339 timestamp)\"),\n duration: z.number().int().min(1).describe(\"Required slot duration in minutes\"),\n timeZone: z.string().optional().default(\"UTC\").describe(\"Timezone for results\"),\n});\n\nexport type FindFreeTimeInput = z.infer<typeof FindFreeTimeSchema>;\n", "import { z } from \"zod\";\n\n/**\n * Gmail's allowed label colors (restricted palette)\n * @see https://developers.google.com/gmail/api/reference/rest/v1/users.labels\n */\nexport const GMAIL_LABEL_COLORS = [\n \"#000000\",\n \"#434343\",\n \"#666666\",\n \"#999999\",\n \"#cccccc\",\n \"#efefef\",\n \"#f3f3f3\",\n \"#ffffff\",\n \"#fb4c2f\",\n \"#ffad47\",\n \"#fad165\",\n \"#16a766\",\n \"#43d692\",\n \"#4a86e8\",\n \"#a479e2\",\n \"#f691b3\",\n \"#f6c5be\",\n \"#ffe6c7\",\n \"#fef1d1\",\n \"#b9e4d0\",\n \"#c6f3de\",\n \"#c9daf8\",\n \"#e4d7f5\",\n \"#fcdee8\",\n \"#efa093\",\n \"#ffd6a2\",\n \"#fce8b3\",\n \"#89d3b2\",\n \"#a0eac9\",\n \"#a4c2f4\",\n \"#d0bcf1\",\n \"#fbc8d9\",\n \"#e66550\",\n \"#ffbc6b\",\n \"#fcda83\",\n \"#5dc28c\",\n \"#74db9b\",\n \"#6d9eeb\",\n \"#b694e8\",\n \"#f7a7c0\",\n \"#cc3a21\",\n \"#eaa041\",\n \"#f2c960\",\n \"#149e60\",\n \"#44b984\",\n \"#3c78d8\",\n \"#8e63ce\",\n \"#e07798\",\n \"#ac2b16\",\n \"#cf8933\",\n \"#d5ae49\",\n \"#0b804b\",\n \"#339966\",\n \"#285bac\",\n \"#653e9b\",\n \"#b65775\",\n \"#822111\",\n \"#a46a21\",\n \"#aa8831\",\n \"#076239\",\n \"#1a764d\",\n \"#1c4587\",\n \"#41236d\",\n \"#83334c\",\n] as const;\n\nexport type GmailLabelColor = (typeof GMAIL_LABEL_COLORS)[number];\n\n/**\n * Schema for validating Gmail label colors (case-insensitive)\n */\nconst gmailLabelColorSchema = z\n .string()\n .refine((color) => GMAIL_LABEL_COLORS.includes(color.toLowerCase() as GmailLabelColor), {\n message: `Invalid Gmail label color. Must be one of: ${GMAIL_LABEL_COLORS.slice(0, 8).join(\", \")}... (see GMAIL_LABEL_COLORS for full list)`,\n })\n .transform((color) => color.toLowerCase());\n\n// Shared schemas\n\n/**\n * Email address with optional display name\n */\nexport const EmailAddressSchema = z.object({\n email: z.string().email(\"Valid email required\"),\n name: z.string().optional().describe(\"Display name\"),\n});\n\nexport type EmailAddressInput = z.infer<typeof EmailAddressSchema>;\n\n/**\n * Attachment for sending emails\n */\nexport const AttachmentSchema = z.object({\n filename: z.string().min(1, \"Filename required\"),\n content: z.string().describe(\"Base64-encoded content\"),\n mimeType: z.string().optional().describe(\"MIME type (auto-detected if not provided)\"),\n});\n\nexport type AttachmentInput = z.infer<typeof AttachmentSchema>;\n\n// Core Email Operations\n\nexport const SendEmailSchema = z.object({\n to: z.array(z.string().email()).min(1, \"At least one recipient required\"),\n subject: z.string().min(1, \"Subject required\"),\n body: z.string().describe(\"Plain text email body\"),\n html: z.string().optional().describe(\"HTML email body (overrides plain text for HTML clients)\"),\n cc: z.array(z.string().email()).optional().describe(\"CC recipients\"),\n bcc: z.array(z.string().email()).optional().describe(\"BCC recipients\"),\n replyTo: z.string().email().optional().describe(\"Reply-to address\"),\n attachments: z.array(AttachmentSchema).optional().describe(\"File attachments\"),\n threadId: z.string().optional().describe(\"Thread ID to reply to\"),\n inReplyTo: z.string().optional().describe(\"Message-ID header for threading\"),\n});\n\nexport type SendEmailInput = z.infer<typeof SendEmailSchema>;\n\nexport const DraftEmailSchema = z.object({\n to: z.array(z.string().email()).optional().describe(\"Recipients (can be empty for drafts)\"),\n subject: z.string().optional().describe(\"Subject (can be empty for drafts)\"),\n body: z.string().optional().describe(\"Plain text email body\"),\n html: z.string().optional().describe(\"HTML email body\"),\n cc: z.array(z.string().email()).optional().describe(\"CC recipients\"),\n bcc: z.array(z.string().email()).optional().describe(\"BCC recipients\"),\n replyTo: z.string().email().optional().describe(\"Reply-to address\"),\n attachments: z.array(AttachmentSchema).optional().describe(\"File attachments\"),\n threadId: z.string().optional().describe(\"Thread ID for draft replies\"),\n});\n\nexport type DraftEmailInput = z.infer<typeof DraftEmailSchema>;\n\nexport const ReadEmailSchema = z.object({\n messageId: z.string().min(1, \"Message ID required\"),\n format: z\n .enum([\"full\", \"metadata\", \"minimal\", \"raw\"])\n .optional()\n .default(\"full\")\n .describe(\"Response format\"),\n contentFormat: z\n .enum([\"full\", \"text\", \"headers\"])\n .optional()\n .default(\"full\")\n .describe(\"Content format: 'full' (text+HTML), 'text' (plain text only), 'headers' (no body)\"),\n});\n\nexport type ReadEmailInput = z.infer<typeof ReadEmailSchema>;\n\nexport const SearchEmailsSchema = z.object({\n query: z\n .string()\n .min(1, \"Search query required\")\n .describe(\"Gmail search query (e.g., 'from:sender@example.com', 'is:unread', 'subject:hello')\"),\n maxResults: z.number().int().min(1).max(500).optional().default(50).describe(\"Maximum results\"),\n pageToken: z.string().optional().describe(\"Token for pagination\"),\n labelIds: z.array(z.string()).optional().describe(\"Filter by label IDs\"),\n includeSpamTrash: z.boolean().optional().default(false).describe(\"Include spam and trash\"),\n});\n\nexport type SearchEmailsInput = z.infer<typeof SearchEmailsSchema>;\n\n/**\n * Schema for deleting emails - supports single ID or array for batch operations\n */\nexport const DeleteEmailSchema = z.object({\n messageId: z\n .union([z.string().min(1), z.array(z.string().min(1)).min(1).max(1000)])\n .describe(\"Message ID or array of IDs (max 1000 for batch)\"),\n});\n\nexport type DeleteEmailInput = z.infer<typeof DeleteEmailSchema>;\n\n/**\n * Schema for modifying email labels - supports single ID or array for batch operations\n */\nexport const ModifyEmailSchema = z.object({\n threadId: z\n .union([z.string().min(1), z.array(z.string().min(1)).min(1).max(1000)])\n .describe(\"Thread ID or array of IDs (max 1000 for batch)\"),\n addLabelIds: z.array(z.string()).optional().describe(\"Label IDs to add\"),\n removeLabelIds: z.array(z.string()).optional().describe(\"Label IDs to remove\"),\n});\n\nexport type ModifyEmailInput = z.infer<typeof ModifyEmailSchema>;\n\nexport const DownloadAttachmentSchema = z.object({\n messageId: z.string().min(1, \"Message ID required\"),\n attachmentId: z.string().min(1, \"Attachment ID required\"),\n filename: z.string().optional().describe(\"Save filename (uses original if not specified)\"),\n outputPath: z.string().optional().describe(\"Output directory path\"),\n});\n\nexport type DownloadAttachmentInput = z.infer<typeof DownloadAttachmentSchema>;\n\n// Label Management\n\nexport const CreateLabelSchema = z.object({\n name: z.string().min(1, \"Label name required\"),\n messageListVisibility: z\n .enum([\"show\", \"hide\"])\n .optional()\n .default(\"show\")\n .describe(\"Show/hide in message list\"),\n labelListVisibility: z\n .enum([\"labelShow\", \"labelShowIfUnread\", \"labelHide\"])\n .optional()\n .default(\"labelShow\")\n .describe(\"Show/hide in label list\"),\n backgroundColor: gmailLabelColorSchema\n .optional()\n .describe(\"Background color from Gmail palette (e.g., #fb4c2f)\"),\n textColor: gmailLabelColorSchema\n .optional()\n .describe(\"Text color from Gmail palette (e.g., #ffffff)\"),\n});\n\nexport type CreateLabelInput = z.infer<typeof CreateLabelSchema>;\n\nexport const UpdateLabelSchema = z.object({\n labelId: z.string().min(1, \"Label ID required\"),\n name: z.string().optional().describe(\"New label name\"),\n messageListVisibility: z.enum([\"show\", \"hide\"]).optional(),\n labelListVisibility: z.enum([\"labelShow\", \"labelShowIfUnread\", \"labelHide\"]).optional(),\n backgroundColor: gmailLabelColorSchema.optional().describe(\"Background color from Gmail palette\"),\n textColor: gmailLabelColorSchema.optional().describe(\"Text color from Gmail palette\"),\n});\n\nexport type UpdateLabelInput = z.infer<typeof UpdateLabelSchema>;\n\nexport const DeleteLabelSchema = z.object({\n labelId: z.string().min(1, \"Label ID required\"),\n});\n\nexport type DeleteLabelInput = z.infer<typeof DeleteLabelSchema>;\n\nexport const ListLabelsSchema = z.object({\n includeSystemLabels: z\n .boolean()\n .optional()\n .default(true)\n .describe(\"Include system labels like INBOX, SENT\"),\n});\n\nexport type ListLabelsInput = z.infer<typeof ListLabelsSchema>;\n\nexport const GetOrCreateLabelSchema = z.object({\n name: z.string().min(1, \"Label name required\"),\n messageListVisibility: z.enum([\"show\", \"hide\"]).optional().default(\"show\"),\n labelListVisibility: z.enum([\"labelShow\", \"labelShowIfUnread\", \"labelHide\"]).optional(),\n backgroundColor: gmailLabelColorSchema.optional(),\n textColor: gmailLabelColorSchema.optional(),\n});\n\nexport type GetOrCreateLabelInput = z.infer<typeof GetOrCreateLabelSchema>;\n\n// Filter Management\n\n/**\n * Filter criteria for matching emails\n */\nexport const FilterCriteriaSchema = z.object({\n from: z.string().optional().describe(\"Match sender\"),\n to: z.string().optional().describe(\"Match recipient\"),\n subject: z.string().optional().describe(\"Match subject\"),\n query: z.string().optional().describe(\"Gmail search query\"),\n hasAttachment: z.boolean().optional().describe(\"Has attachment\"),\n excludeChats: z.boolean().optional().default(true).describe(\"Exclude chat messages\"),\n size: z.number().int().optional().describe(\"Size threshold in bytes\"),\n sizeComparison: z.enum([\"larger\", \"smaller\"]).optional().describe(\"Size comparison\"),\n});\n\nexport type FilterCriteriaInput = z.infer<typeof FilterCriteriaSchema>;\n\n/**\n * Actions to perform on matching emails\n */\nexport const FilterActionSchema = z.object({\n addLabelIds: z.array(z.string()).optional().describe(\"Label IDs to add\"),\n removeLabelIds: z.array(z.string()).optional().describe(\"Label IDs to remove\"),\n forward: z.string().email().optional().describe(\"Forward to email address\"),\n});\n\nexport type FilterActionInput = z.infer<typeof FilterActionSchema>;\n\n/**\n * Template types for common filter use cases\n */\nexport const FilterTemplateType = z.enum([\n \"fromSender\",\n \"withSubject\",\n \"withAttachments\",\n \"largeEmails\",\n \"mailingList\",\n]);\n\nexport type FilterTemplateTypeValue = z.infer<typeof FilterTemplateType>;\n\n/**\n * Create filter - supports direct criteria/action or pre-built templates\n */\nexport const CreateFilterSchema = z\n .object({\n // Direct mode\n criteria: FilterCriteriaSchema.optional(),\n action: FilterActionSchema.optional(),\n // Template mode\n template: FilterTemplateType.optional().describe(\"Use a pre-built template\"),\n labelIds: z.array(z.string()).optional().describe(\"Label IDs for template mode\"),\n archive: z.boolean().optional().default(false).describe(\"Remove from inbox (template mode)\"),\n email: z.string().email().optional().describe(\"Email address (for fromSender, mailingList)\"),\n subject: z.string().optional().describe(\"Subject text (for withSubject)\"),\n sizeBytes: z.number().int().optional().describe(\"Size in bytes (for largeEmails)\"),\n listAddress: z.string().optional().describe(\"Mailing list address (for mailingList)\"),\n })\n .refine(\n (data) => {\n // Either direct mode or template mode\n if (data.template) {\n // Template mode requires labelIds\n if (!data.labelIds || data.labelIds.length === 0) return false;\n // Template-specific validation\n switch (data.template) {\n case \"fromSender\":\n return !!data.email;\n case \"withSubject\":\n return !!data.subject;\n case \"largeEmails\":\n return !!data.sizeBytes;\n case \"mailingList\":\n return !!data.listAddress || !!data.email;\n case \"withAttachments\":\n return true;\n }\n } else {\n // Direct mode requires criteria and action\n return !!data.criteria && !!data.action;\n }\n },\n {\n message:\n \"Provide either (criteria + action) for direct mode, or (template + labelIds) for template mode\",\n },\n );\n\nexport type CreateFilterInput = z.infer<typeof CreateFilterSchema>;\n\nexport const ListFiltersSchema = z.object({\n filterId: z\n .string()\n .optional()\n .describe(\"Optional filter ID to get details of a specific filter\"),\n});\n\nexport type ListFiltersInput = z.infer<typeof ListFiltersSchema>;\n\nexport const DeleteFilterSchema = z.object({\n filterId: z.string().min(1, \"Filter ID required\"),\n});\n\nexport type DeleteFilterInput = z.infer<typeof DeleteFilterSchema>;\n", "import type { drive_v3 } from \"googleapis\";\nimport type { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { log } from \"../utils/index.js\";\nimport {\n GOOGLE_MIME_TYPES,\n TEXT_MIME_TYPES as MIME_TEXT_TYPES,\n getExtension,\n getMimeTypeFromExtension,\n} from \"../utils/mimeTypes.js\";\nimport { escapeQueryString, combineQueries } from \"../utils/gdrive-query.js\";\nimport {\n getCachedPath,\n setCachedPath,\n getCachedSegment,\n setCachedSegment,\n} from \"../utils/pathCache.js\";\n\n/**\n * Context passed to handlers for access to MCP features like progress and elicitation\n */\nexport interface HandlerContext {\n /** The MCP server instance */\n server: Server;\n /** Progress token from the client request (if provided) */\n progressToken?: string | number;\n}\n\n// Re-export FOLDER_MIME_TYPE for backward compatibility\nexport const FOLDER_MIME_TYPE = GOOGLE_MIME_TYPES.FOLDER;\n\n// Re-export TEXT_MIME_TYPES for backward compatibility\nexport const TEXT_MIME_TYPES: Record<string, string> = {\n txt: MIME_TEXT_TYPES.PLAIN,\n md: MIME_TEXT_TYPES.MARKDOWN,\n};\n\nexport function getExtensionFromFilename(filename: string): string {\n return getExtension(filename);\n}\n\nexport function getMimeTypeFromFilename(filename: string): string {\n return getMimeTypeFromExtension(filename);\n}\n\n/**\n * For text-based files, ensure they have a valid extension.\n */\nexport function validateTextFileExtension(name: string): void {\n const ext = getExtensionFromFilename(name);\n if (![\"txt\", \"md\"].includes(ext)) {\n throw new Error(\"File name must end with .txt or .md for text files.\");\n }\n}\n\ninterface ResolvePathOptions {\n /** Create intermediate folders if they don't exist (default: true) */\n createIfMissing?: boolean;\n}\n\n/**\n * Core path resolution function. Resolves a slash-delimited path to a folder ID.\n *\n * @param drive - Google Drive API instance\n * @param pathStr - Path to resolve (e.g., \"/some/folder\")\n * @param options - Resolution options\n * @returns The resolved folder ID\n */\nasync function resolvePathCore(\n drive: drive_v3.Drive,\n pathStr: string,\n options: ResolvePathOptions = {},\n): Promise<string> {\n const { createIfMissing = true } = options;\n\n if (!pathStr || pathStr === \"/\") return \"root\";\n\n // Check full path cache first\n const cachedPath = getCachedPath(pathStr);\n if (cachedPath) {\n log(\"Path cache hit\", { path: pathStr, fileId: cachedPath });\n return cachedPath;\n }\n\n const parts = pathStr.replace(/^\\/+|\\/+$/g, \"\").split(\"/\");\n let currentFolderId: string = \"root\";\n\n for (const part of parts) {\n if (!part) continue;\n\n // Check segment cache\n const cachedSegment = getCachedSegment(currentFolderId, part);\n if (cachedSegment) {\n currentFolderId = cachedSegment;\n continue;\n }\n\n const escapedPart = escapeQueryString(part);\n const response = await drive.files.list({\n q: combineQueries(\n `'${currentFolderId}' in parents`,\n `name = '${escapedPart}'`,\n `mimeType = '${FOLDER_MIME_TYPE}'`,\n \"trashed = false\",\n ),\n fields: \"files(id)\",\n spaces: \"drive\",\n includeItemsFromAllDrives: true,\n supportsAllDrives: true,\n });\n\n if (!response.data.files?.length) {\n if (!createIfMissing) {\n throw new Error(`Folder not found: ${part} in path ${pathStr}`);\n }\n\n // Create the missing folder\n const folder = await drive.files.create({\n requestBody: {\n name: part,\n mimeType: FOLDER_MIME_TYPE,\n parents: [currentFolderId],\n },\n fields: \"id\",\n supportsAllDrives: true,\n });\n\n if (!folder.data.id) {\n throw new Error(`Failed to create intermediate folder: ${part}`);\n }\n\n setCachedSegment(currentFolderId, part, folder.data.id);\n currentFolderId = folder.data.id;\n } else {\n const foundId = response.data.files[0].id!;\n setCachedSegment(currentFolderId, part, foundId);\n currentFolderId = foundId;\n }\n }\n\n setCachedPath(pathStr, currentFolderId);\n return currentFolderId;\n}\n\n/**\n * Resolve a slash-delimited path (e.g. \"/some/folder\") within Google Drive\n * into a folder ID. Creates folders if they don't exist.\n */\nexport async function resolvePath(drive: drive_v3.Drive, pathStr: string): Promise<string> {\n return resolvePathCore(drive, pathStr, { createIfMissing: true });\n}\n\n/**\n * Resolve a folder ID or path.\n * If it's a path (starts with '/'), resolve it.\n * If no folder is provided, return 'root'.\n */\nexport async function resolveFolderId(\n drive: drive_v3.Drive,\n input: string | undefined,\n): Promise<string> {\n if (!input) return \"root\";\n\n if (input.startsWith(\"/\")) {\n // Input is a path\n return resolvePath(drive, input);\n } else {\n // Input is a folder ID, return as-is\n return input;\n }\n}\n\n/**\n * Resolve optional folder parameters where user can provide either folderId OR folderPath.\n * Throws if both are provided. Returns 'root' if neither is provided.\n * Creates intermediate folders if folderPath doesn't exist.\n */\nexport async function resolveOptionalFolderPath(\n drive: drive_v3.Drive,\n folderId?: string,\n folderPath?: string,\n): Promise<string> {\n if (folderId && folderPath) {\n throw new Error(\"Provide either folderId or folderPath, not both\");\n }\n if (folderId) return folderId;\n if (folderPath) return resolvePath(drive, folderPath);\n return \"root\";\n}\n\n/**\n * Resolve a file by ID or path. Returns the file ID.\n * Unlike folder resolution, this does NOT create the file if it doesn't exist.\n */\nexport async function resolveFileIdFromPath(\n drive: drive_v3.Drive,\n fileId?: string,\n filePath?: string,\n): Promise<string> {\n if (fileId && filePath) {\n throw new Error(\"Provide either fileId or filePath, not both\");\n }\n if (!fileId && !filePath) {\n throw new Error(\"Either fileId or filePath must be provided\");\n }\n if (fileId) return fileId;\n\n // Parse path to get parent folder and filename\n const normalizedPath = filePath!.replace(/^\\/+|\\/+$/g, \"\");\n const parts = normalizedPath.split(\"/\");\n const fileName = parts.pop();\n\n if (!fileName) {\n throw new Error(\"Invalid file path: no filename specified\");\n }\n\n // Resolve parent folder (don't create if missing)\n let parentFolderId = \"root\";\n if (parts.length > 0) {\n const parentPath = \"/\" + parts.join(\"/\");\n parentFolderId = await resolvePathWithoutCreate(drive, parentPath);\n }\n\n // Find the file in the parent folder\n const escapedName = escapeQueryString(fileName);\n const response = await drive.files.list({\n q: combineQueries(\n `'${parentFolderId}' in parents`,\n `name = '${escapedName}'`,\n \"trashed = false\",\n ),\n fields: \"files(id, name)\",\n pageSize: 1,\n includeItemsFromAllDrives: true,\n supportsAllDrives: true,\n });\n\n if (!response.data.files?.length) {\n throw new Error(`File not found: ${filePath}`);\n }\n\n return response.data.files[0].id!;\n}\n\n/**\n * Resolve a path without creating folders. Throws if any folder doesn't exist.\n */\nasync function resolvePathWithoutCreate(drive: drive_v3.Drive, pathStr: string): Promise<string> {\n return resolvePathCore(drive, pathStr, { createIfMissing: false });\n}\n\n/**\n * Result of checking file existence. Discriminated union allows callers to\n * distinguish \"file not found\" from \"API error\".\n */\nexport type FileExistsResult =\n | { status: \"found\"; id: string }\n | { status: \"not_found\" }\n | { status: \"error\"; error: Error };\n\n/**\n * Check if a file with the given name already exists in the specified folder.\n * Returns a discriminated union allowing callers to distinguish between\n * \"file found\", \"file not found\", and \"API error\" cases.\n */\nexport async function checkFileExistsResult(\n drive: drive_v3.Drive,\n name: string,\n parentFolderId: string = \"root\",\n): Promise<FileExistsResult> {\n try {\n const escapedName = escapeQueryString(name);\n const query = combineQueries(\n `name = '${escapedName}'`,\n `'${parentFolderId}' in parents`,\n \"trashed = false\",\n );\n\n const res = await drive.files.list({\n q: query,\n fields: \"files(id, name, mimeType)\",\n pageSize: 1,\n includeItemsFromAllDrives: true,\n supportsAllDrives: true,\n });\n\n if (res.data.files && res.data.files.length > 0 && res.data.files[0].id) {\n return { status: \"found\", id: res.data.files[0].id };\n }\n return { status: \"not_found\" };\n } catch (error) {\n log(\"Error checking file existence:\", error);\n return { status: \"error\", error: error instanceof Error ? error : new Error(String(error)) };\n }\n}\n\n/**\n * Check if a file with the given name already exists in the specified folder.\n * Returns the file ID if it exists, null otherwise.\n *\n * @deprecated Use checkFileExistsResult() for better error handling.\n * This function cannot distinguish \"file not found\" from \"API error\".\n */\nexport async function checkFileExists(\n drive: drive_v3.Drive,\n name: string,\n parentFolderId: string = \"root\",\n): Promise<string | null> {\n const result = await checkFileExistsResult(drive, name, parentFolderId);\n if (result.status === \"found\") {\n return result.id;\n }\n return null;\n}\n\n/**\n * Convert A1 notation to GridRange for Google Sheets API\n */\nexport function convertA1ToGridRange(\n a1Notation: string,\n sheetId: number,\n): {\n sheetId: number;\n startColumnIndex?: number;\n endColumnIndex?: number;\n startRowIndex?: number;\n endRowIndex?: number;\n} {\n const rangeRegex = /^([A-Z]*)([0-9]*)(:([A-Z]*)([0-9]*))?$/;\n const match = a1Notation.match(rangeRegex);\n\n if (!match) {\n throw new Error(`Invalid A1 notation: ${a1Notation}`);\n }\n\n const [, startCol, startRow, , endCol, endRow] = match;\n\n const gridRange: {\n sheetId: number;\n startColumnIndex?: number;\n endColumnIndex?: number;\n startRowIndex?: number;\n endRowIndex?: number;\n } = { sheetId };\n\n // Convert column letters to numbers (A=0, B=1, etc.)\n const colToNum = (col: string): number => {\n let num = 0;\n for (let i = 0; i < col.length; i++) {\n num = num * 26 + (col.charCodeAt(i) - \"A\".charCodeAt(0) + 1);\n }\n return num - 1;\n };\n\n // Set start indices\n if (startCol) gridRange.startColumnIndex = colToNum(startCol);\n if (startRow) gridRange.startRowIndex = parseInt(startRow) - 1;\n\n // Set end indices (exclusive)\n if (endCol) {\n gridRange.endColumnIndex = colToNum(endCol) + 1;\n } else if (startCol && !endCol) {\n gridRange.endColumnIndex = gridRange.startColumnIndex! + 1;\n }\n\n if (endRow) {\n gridRange.endRowIndex = parseInt(endRow);\n } else if (startRow && !endRow) {\n gridRange.endRowIndex = gridRange.startRowIndex! + 1;\n }\n\n return gridRange;\n}\n\n// -----------------------------------------------------------------------------\n// EMU (English Metric Units) Conversion Helpers\n// -----------------------------------------------------------------------------\n// EMU is the native unit for Google Slides positioning. These constants and\n// functions help convert to/from common units.\n\nexport const EMU_PER_INCH = 914400;\nexport const EMU_PER_POINT = 12700;\nexport const EMU_PER_PIXEL_96DPI = 9525;\n\n// Standard Google Slides dimensions in EMU (default 16:9 aspect ratio)\nexport const SLIDES_WIDTH_EMU = 9144000; // 10 inches\nexport const SLIDES_HEIGHT_EMU = 5143500; // ~5.625 inches\n\nexport function inchesToEmu(inches: number): number {\n return Math.round(inches * EMU_PER_INCH);\n}\n\nexport function pointsToEmu(points: number): number {\n return Math.round(points * EMU_PER_POINT);\n}\n\nexport function pixelsToEmu(pixels: number, dpi = 96): number {\n return Math.round((pixels * EMU_PER_INCH) / dpi);\n}\n\nexport function emuToInches(emu: number): number {\n return emu / EMU_PER_INCH;\n}\n\nexport function emuToPoints(emu: number): number {\n return emu / EMU_PER_POINT;\n}\n\nexport function emuToPixels(emu: number, dpi = 96): number {\n return (emu * dpi) / EMU_PER_INCH;\n}\n\n// -----------------------------------------------------------------------------\n// Batch Operation Helpers\n// -----------------------------------------------------------------------------\n\nexport interface BatchResult<T> {\n success: T[];\n failed: Array<{ id: string; error: string }>;\n}\n\ninterface BatchOperationOptions {\n operationName: string;\n concurrency?: number;\n}\n\n/**\n * Generic batch operation processor that handles progress reporting vs rate-limited modes\n * and normalizes results into success/failed arrays.\n *\n * This abstracts the common pattern used by handleBatchDelete, handleBatchMove, handleBatchShare.\n */\nexport async function processBatchOperation<T>(\n ids: string[],\n operation: (id: string) => Promise<T>,\n context: HandlerContext | undefined,\n options: BatchOperationOptions,\n): Promise<BatchResult<T>> {\n // Dynamically import utils to avoid circular dependencies\n const { processBatchWithProgress, withRateLimitedBatch } = await import(\"../utils/index.js\");\n\n const concurrency = options.concurrency ?? 5;\n\n // Choose processing mode based on context availability\n const results = context?.server\n ? await processBatchWithProgress({\n server: context.server,\n progressToken: context.progressToken,\n items: ids,\n processor: operation,\n concurrency,\n operationName: options.operationName,\n })\n : await withRateLimitedBatch(ids, operation, {\n concurrency,\n operationName: options.operationName,\n });\n\n // Normalize results into success/failed arrays\n const success: T[] = [];\n const failed: Array<{ id: string; error: string }> = [];\n\n results.forEach((result, index) => {\n if (result.success) {\n success.push(result.result);\n } else {\n failed.push({\n id: ids[index],\n error: result.error,\n });\n }\n });\n\n return { success, failed };\n}\n", "/**\n * MIME type constants and mappings for Google Drive file types.\n * Consolidates duplicated MIME type definitions across handlers.\n */\n\n/** Google Workspace MIME types */\nexport const GOOGLE_MIME_TYPES = {\n DOCUMENT: \"application/vnd.google-apps.document\",\n SPREADSHEET: \"application/vnd.google-apps.spreadsheet\",\n PRESENTATION: \"application/vnd.google-apps.presentation\",\n FOLDER: \"application/vnd.google-apps.folder\",\n DRAWING: \"application/vnd.google-apps.drawing\",\n FORM: \"application/vnd.google-apps.form\",\n SCRIPT: \"application/vnd.google-apps.script\",\n SITE: \"application/vnd.google-apps.site\",\n SHORTCUT: \"application/vnd.google-apps.shortcut\",\n} as const;\n\n/** Text file MIME types */\nexport const TEXT_MIME_TYPES = {\n PLAIN: \"text/plain\",\n MARKDOWN: \"text/markdown\",\n CSV: \"text/csv\",\n HTML: \"text/html\",\n} as const;\n\n/** Export MIME types for downloading Google Workspace files */\nexport const EXPORT_MIME_TYPES = {\n PDF: \"application/pdf\",\n DOCX: \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n XLSX: \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n PPTX: \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\n RTF: \"application/rtf\",\n ODT: \"application/vnd.oasis.opendocument.text\",\n ODS: \"application/vnd.oasis.opendocument.spreadsheet\",\n ODP: \"application/vnd.oasis.opendocument.presentation\",\n ZIP: \"application/zip\",\n EPUB: \"application/epub+zip\",\n} as const;\n\n/** File type categories */\nexport type FileType = \"doc\" | \"sheet\" | \"slides\" | \"text\";\n\n/** Map file extensions to their type category */\nexport const EXTENSION_TO_TYPE: Record<string, FileType> = {\n // Google Doc types\n docx: \"doc\",\n doc: \"doc\",\n gdoc: \"doc\",\n odt: \"doc\",\n rtf: \"doc\",\n // Google Sheet types\n xlsx: \"sheet\",\n xls: \"sheet\",\n csv: \"sheet\",\n gsheet: \"sheet\",\n ods: \"sheet\",\n // Google Slides types\n pptx: \"slides\",\n ppt: \"slides\",\n gslides: \"slides\",\n odp: \"slides\",\n // Text types\n txt: \"text\",\n md: \"text\",\n};\n\n/** Map file extensions to their MIME type */\nexport const EXTENSION_TO_MIME: Record<string, string> = {\n txt: TEXT_MIME_TYPES.PLAIN,\n md: TEXT_MIME_TYPES.MARKDOWN,\n csv: TEXT_MIME_TYPES.CSV,\n html: TEXT_MIME_TYPES.HTML,\n};\n\n/**\n * Get the file extension from a filename.\n */\nexport function getExtension(filename: string): string {\n return filename.split(\".\").pop()?.toLowerCase() || \"\";\n}\n\n/**\n * Infer file type from filename extension.\n */\nexport function inferTypeFromExtension(filename: string): FileType | undefined {\n const ext = getExtension(filename);\n return EXTENSION_TO_TYPE[ext];\n}\n\n/**\n * Get MIME type from filename extension for text files.\n */\nexport function getMimeTypeFromExtension(filename: string): string {\n const ext = getExtension(filename);\n return EXTENSION_TO_MIME[ext] || TEXT_MIME_TYPES.PLAIN;\n}\n\n/**\n * Check if a MIME type is a Google Workspace type.\n */\nexport function isGoogleWorkspaceMimeType(mimeType: string): boolean {\n return mimeType.startsWith(\"application/vnd.google-apps.\");\n}\n\n/**\n * Check if a MIME type is a folder.\n */\nexport function isFolder(mimeType: string): boolean {\n return mimeType === GOOGLE_MIME_TYPES.FOLDER;\n}\n\n/**\n * Get the file type category from a Google Workspace MIME type.\n */\nexport function getTypeFromGoogleMime(mimeType: string): FileType | undefined {\n switch (mimeType) {\n case GOOGLE_MIME_TYPES.DOCUMENT:\n return \"doc\";\n case GOOGLE_MIME_TYPES.SPREADSHEET:\n return \"sheet\";\n case GOOGLE_MIME_TYPES.PRESENTATION:\n return \"slides\";\n default:\n return undefined;\n }\n}\n\n/**\n * Returns a suggestion for which tool to use based on the file's MIME type.\n * Used when a user calls the wrong specific handler (e.g., getGoogleDocContent on a Sheet).\n */\nexport function getMimeTypeSuggestion(mimeType: string | null | undefined): string {\n switch (mimeType) {\n case GOOGLE_MIME_TYPES.DOCUMENT:\n return \"Use getGoogleDocContent for Google Docs.\";\n case GOOGLE_MIME_TYPES.SPREADSHEET:\n return \"Use getGoogleSheetContent for spreadsheets.\";\n case GOOGLE_MIME_TYPES.PRESENTATION:\n return \"Use getGoogleSlidesContent for presentations.\";\n default:\n return \"Use getFileContent for automatic type detection.\";\n }\n}\n", "import type { drive_v3, docs_v1 } from \"googleapis\";\nimport {\n log,\n successResponse,\n structuredResponse,\n errorResponse,\n withTimeout,\n validateArgs,\n} from \"../utils/index.js\";\nimport { GOOGLE_MIME_TYPES, getMimeTypeSuggestion } from \"../utils/mimeTypes.js\";\nimport type { ToolResponse } from \"../utils/index.js\";\nimport {\n CreateGoogleDocSchema,\n UpdateGoogleDocSchema,\n GetGoogleDocContentSchema,\n AppendToDocSchema,\n InsertTextInDocSchema,\n DeleteTextInDocSchema,\n ReplaceTextInDocSchema,\n FormatGoogleDocRangeSchema,\n} from \"../schemas/index.js\";\nimport { resolveOptionalFolderPath, checkFileExists } from \"./helpers.js\";\nimport { toDocsColorStyle } from \"../utils/colors.js\";\n\n/**\n * Get the end index of a Google Doc's content.\n * Used for calculating document length and insert positions.\n */\nfunction getDocumentEndIndex(document: docs_v1.Schema$Document): number {\n const content = document.body?.content;\n if (!content || content.length === 0) return 1;\n return content[content.length - 1]?.endIndex || 1;\n}\n\nexport async function handleCreateGoogleDoc(\n drive: drive_v3.Drive,\n docs: docs_v1.Docs,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(CreateGoogleDocSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n const parentFolderId = await resolveOptionalFolderPath(\n drive,\n data.parentFolderId,\n data.parentPath,\n );\n\n // Check if document already exists\n const existingFileId = await checkFileExists(drive, data.name, parentFolderId);\n if (existingFileId) {\n return errorResponse(\n `A document named \"${data.name}\" already exists in this location. ` +\n `To update it, use updateGoogleDoc with documentId: ${existingFileId}`,\n { code: \"ALREADY_EXISTS\", context: { existingFileId } },\n );\n }\n\n log(\"Creating Google Doc\", { parentFolderId });\n\n // Create empty doc\n let docResponse;\n try {\n docResponse = await drive.files.create({\n requestBody: {\n name: data.name,\n mimeType: \"application/vnd.google-apps.document\",\n parents: [parentFolderId],\n },\n fields: \"id, name, webViewLink\",\n supportsAllDrives: true,\n });\n } catch (createError: unknown) {\n const err = createError as {\n message?: string;\n code?: number;\n errors?: unknown;\n status?: number;\n };\n log(\"Drive files.create error details:\", {\n message: err.message,\n code: err.code,\n errors: err.errors,\n status: err.status,\n });\n throw createError;\n }\n const doc = docResponse.data;\n\n await docs.documents.batchUpdate({\n documentId: doc.id!,\n requestBody: {\n requests: [\n {\n insertText: { location: { index: 1 }, text: data.content },\n },\n // Ensure the text is formatted as normal text, not as a header\n {\n updateParagraphStyle: {\n range: {\n startIndex: 1,\n endIndex: data.content.length + 1,\n },\n paragraphStyle: {\n namedStyleType: \"NORMAL_TEXT\",\n },\n fields: \"namedStyleType\",\n },\n },\n ],\n },\n });\n\n return successResponse(\n `Created Google Doc: ${doc.name}\\nID: ${doc.id}\\nLink: ${doc.webViewLink}`,\n );\n}\n\nexport async function handleUpdateGoogleDoc(\n docs: docs_v1.Docs,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(UpdateGoogleDocSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n const document = await docs.documents.get({ documentId: data.documentId });\n\n // Delete all content\n const endIndex = getDocumentEndIndex(document.data);\n\n // Google Docs API doesn't allow deleting the final newline character\n // We need to leave at least one character in the document\n const deleteEndIndex = Math.max(1, endIndex - 1);\n\n if (deleteEndIndex > 1) {\n await docs.documents.batchUpdate({\n documentId: data.documentId,\n requestBody: {\n requests: [\n {\n deleteContentRange: {\n range: { startIndex: 1, endIndex: deleteEndIndex },\n },\n },\n ],\n },\n });\n }\n\n // Insert new content\n await docs.documents.batchUpdate({\n documentId: data.documentId,\n requestBody: {\n requests: [\n {\n insertText: { location: { index: 1 }, text: data.content },\n },\n // Ensure the text is formatted as normal text, not as a header\n {\n updateParagraphStyle: {\n range: {\n startIndex: 1,\n endIndex: data.content.length + 1,\n },\n paragraphStyle: {\n namedStyleType: \"NORMAL_TEXT\",\n },\n fields: \"namedStyleType\",\n },\n },\n ],\n },\n });\n\n return successResponse(`Updated Google Doc: ${document.data.title}`);\n}\n\nexport async function handleGetGoogleDocContent(\n drive: drive_v3.Drive,\n docs: docs_v1.Docs,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(GetGoogleDocContentSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Check file type before calling Docs API to provide helpful error messages\n const metadata = await drive.files.get({\n fileId: data.documentId,\n fields: \"mimeType,name\",\n supportsAllDrives: true,\n });\n\n const mimeType = metadata.data.mimeType;\n if (mimeType !== GOOGLE_MIME_TYPES.DOCUMENT) {\n const fileName = metadata.data.name || data.documentId;\n const suggestion = getMimeTypeSuggestion(mimeType);\n return errorResponse(`\"${fileName}\" is not a Google Doc (type: ${mimeType}). ${suggestion}`);\n }\n\n const document = await withTimeout(\n docs.documents.get({ documentId: data.documentId }),\n 30000,\n \"Get document content\",\n );\n\n const contentSegments: Array<{\n startIndex: number;\n endIndex: number;\n text: string;\n }> = [];\n let content = \"\";\n let currentIndex = 1;\n\n // Extract text content with indices\n if (document.data.body?.content) {\n for (const element of document.data.body.content) {\n if (element.paragraph?.elements) {\n for (const textElement of element.paragraph.elements) {\n if (textElement.textRun?.content) {\n const text = textElement.textRun.content;\n const startIdx = currentIndex;\n content += text;\n currentIndex += text.length;\n contentSegments.push({\n startIndex: startIdx,\n endIndex: currentIndex,\n text: text,\n });\n }\n }\n }\n }\n }\n\n // Format the response to show text with indices\n let formattedContent = \"Document content with indices:\\n\\n\";\n let lineStart = 1;\n const lines = content.split(\"\\n\");\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const lineEnd = lineStart + line.length;\n if (line.trim()) {\n formattedContent += `[${lineStart}-${lineEnd}] ${line}\\n`;\n }\n lineStart = lineEnd + 1; // +1 for the newline character\n }\n\n const textResponse = formattedContent + `\\nTotal length: ${content.length} characters`;\n\n return structuredResponse(textResponse, {\n documentId: data.documentId,\n title: document.data.title,\n content: contentSegments,\n totalLength: content.length,\n });\n}\n\nexport async function handleAppendToDoc(docs: docs_v1.Docs, args: unknown): Promise<ToolResponse> {\n const validation = validateArgs(AppendToDocSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Get document to find end index\n const document = await docs.documents.get({ documentId: data.documentId });\n const endIndex = getDocumentEndIndex(document.data);\n\n // Insert at end index - 1 (before the final newline)\n const insertIndex = Math.max(1, endIndex - 1);\n\n // Prepare the text to insert\n const textToInsert = data.insertNewline ? `\\n${data.text}` : data.text;\n\n await docs.documents.batchUpdate({\n documentId: data.documentId,\n requestBody: {\n requests: [\n {\n insertText: {\n location: { index: insertIndex },\n text: textToInsert,\n },\n },\n ],\n },\n });\n\n log(\"Text appended to document\", {\n documentId: data.documentId,\n textLength: data.text.length,\n });\n\n return successResponse(\n `Appended ${data.text.length} characters to document \"${document.data.title}\"`,\n );\n}\n\nexport async function handleInsertTextInDoc(\n docs: docs_v1.Docs,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(InsertTextInDocSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Get document to validate index and get title\n const document = await docs.documents.get({ documentId: data.documentId });\n const docLength = getDocumentEndIndex(document.data);\n\n if (data.index >= docLength) {\n return errorResponse(\n `Index ${data.index} is beyond the document length (${docLength - 1} characters). ` +\n `Use appendToDoc to add text at the end, or specify an index between 1 and ${docLength - 1}.`,\n );\n }\n\n await docs.documents.batchUpdate({\n documentId: data.documentId,\n requestBody: {\n requests: [\n {\n insertText: {\n location: { index: data.index },\n text: data.text,\n },\n },\n ],\n },\n });\n\n log(\"Text inserted into document\", {\n documentId: data.documentId,\n index: data.index,\n textLength: data.text.length,\n });\n\n return successResponse(\n `Inserted ${data.text.length} characters at index ${data.index} in \"${document.data.title}\"`,\n );\n}\n\nexport async function handleDeleteTextInDoc(\n docs: docs_v1.Docs,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(DeleteTextInDocSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Get document to validate indices and get title\n const document = await docs.documents.get({ documentId: data.documentId });\n const docLength = getDocumentEndIndex(document.data);\n\n if (data.endIndex > docLength) {\n return errorResponse(\n `End index ${data.endIndex} is beyond the document length (${docLength - 1} characters). ` +\n `Valid range is 1 to ${docLength - 1}.`,\n );\n }\n\n const charsToDelete = data.endIndex - data.startIndex;\n\n await docs.documents.batchUpdate({\n documentId: data.documentId,\n requestBody: {\n requests: [\n {\n deleteContentRange: {\n range: {\n startIndex: data.startIndex,\n endIndex: data.endIndex,\n },\n },\n },\n ],\n },\n });\n\n log(\"Text deleted from document\", {\n documentId: data.documentId,\n startIndex: data.startIndex,\n endIndex: data.endIndex,\n });\n\n return successResponse(\n `Deleted ${charsToDelete} characters (indices ${data.startIndex}-${data.endIndex}) from \"${document.data.title}\"`,\n );\n}\n\nexport async function handleReplaceTextInDoc(\n docs: docs_v1.Docs,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(ReplaceTextInDocSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Get document title\n const document = await docs.documents.get({ documentId: data.documentId });\n\n const response = await docs.documents.batchUpdate({\n documentId: data.documentId,\n requestBody: {\n requests: [\n {\n replaceAllText: {\n containsText: {\n text: data.searchText,\n matchCase: data.matchCase,\n },\n replaceText: data.replaceText,\n },\n },\n ],\n },\n });\n\n // Get the number of replacements made\n const occurrencesChanged = response.data.replies?.[0]?.replaceAllText?.occurrencesChanged || 0;\n\n log(\"Text replaced in document\", {\n documentId: data.documentId,\n occurrences: occurrencesChanged,\n });\n\n if (occurrencesChanged === 0) {\n return successResponse(\n `No occurrences of \"${data.searchText}\" found in \"${document.data.title}\"`,\n );\n }\n\n return successResponse(\n `Replaced ${occurrencesChanged} occurrence(s) of \"${data.searchText}\" with \"${data.replaceText}\" in \"${document.data.title}\"`,\n );\n}\n\n// -----------------------------------------------------------------------------\n// DOC FORMATTING HELPERS\n// -----------------------------------------------------------------------------\n\ninterface DocTextFormatOptions {\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n strikethrough?: boolean;\n fontSize?: number;\n fontFamily?: string;\n foregroundColor?: { red?: number; green?: number; blue?: number };\n}\n\nfunction buildDocTextStyle(data: DocTextFormatOptions): {\n style: Record<string, unknown>;\n fields: string[];\n} {\n const style: Record<string, unknown> = {};\n const fields: string[] = [];\n\n if (data.bold !== undefined) {\n style.bold = data.bold;\n fields.push(\"bold\");\n }\n if (data.italic !== undefined) {\n style.italic = data.italic;\n fields.push(\"italic\");\n }\n if (data.underline !== undefined) {\n style.underline = data.underline;\n fields.push(\"underline\");\n }\n if (data.strikethrough !== undefined) {\n style.strikethrough = data.strikethrough;\n fields.push(\"strikethrough\");\n }\n if (data.fontSize !== undefined) {\n style.fontSize = { magnitude: data.fontSize, unit: \"PT\" };\n fields.push(\"fontSize\");\n }\n if (data.fontFamily !== undefined) {\n style.weightedFontFamily = { fontFamily: data.fontFamily };\n fields.push(\"weightedFontFamily\");\n }\n if (data.foregroundColor) {\n style.foregroundColor = toDocsColorStyle(data.foregroundColor);\n fields.push(\"foregroundColor\");\n }\n\n return { style, fields };\n}\n\ninterface DocParagraphFormatOptions {\n namedStyleType?: string;\n alignment?: string;\n lineSpacing?: number;\n spaceAbove?: number;\n spaceBelow?: number;\n}\n\nfunction buildDocParagraphStyle(data: DocParagraphFormatOptions): {\n style: Record<string, unknown>;\n fields: string[];\n} {\n const style: Record<string, unknown> = {};\n const fields: string[] = [];\n\n if (data.namedStyleType !== undefined) {\n style.namedStyleType = data.namedStyleType;\n fields.push(\"namedStyleType\");\n }\n if (data.alignment !== undefined) {\n style.alignment = data.alignment;\n fields.push(\"alignment\");\n }\n if (data.lineSpacing !== undefined) {\n style.lineSpacing = data.lineSpacing;\n fields.push(\"lineSpacing\");\n }\n if (data.spaceAbove !== undefined) {\n style.spaceAbove = { magnitude: data.spaceAbove, unit: \"PT\" };\n fields.push(\"spaceAbove\");\n }\n if (data.spaceBelow !== undefined) {\n style.spaceBelow = { magnitude: data.spaceBelow, unit: \"PT\" };\n fields.push(\"spaceBelow\");\n }\n\n return { style, fields };\n}\n\n// -----------------------------------------------------------------------------\n// DOC FORMATTING HANDLER\n// -----------------------------------------------------------------------------\n\nexport async function handleFormatGoogleDocRange(\n docs: docs_v1.Docs,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(FormatGoogleDocRangeSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n const document = await docs.documents.get({ documentId: data.documentId });\n const docEndIndex = getDocumentEndIndex(document.data);\n const startIndex = data.startIndex ?? 1;\n const endIndex = data.endIndex ?? docEndIndex;\n\n const requests: docs_v1.Schema$Request[] = [];\n const formatsApplied: string[] = [];\n\n const textResult = buildDocTextStyle(data);\n if (textResult.fields.length > 0) {\n requests.push({\n updateTextStyle: {\n range: { startIndex, endIndex },\n textStyle: textResult.style,\n fields: textResult.fields.join(\",\"),\n },\n });\n formatsApplied.push(...textResult.fields);\n }\n\n const paragraphResult = buildDocParagraphStyle(data);\n if (paragraphResult.fields.length > 0) {\n requests.push({\n updateParagraphStyle: {\n range: { startIndex, endIndex },\n paragraphStyle: paragraphResult.style,\n fields: paragraphResult.fields.join(\",\"),\n },\n });\n formatsApplied.push(...paragraphResult.fields);\n }\n\n if (requests.length === 0) {\n return errorResponse(\n \"No formatting options specified. Provide at least one of: \" +\n \"bold, italic, underline, strikethrough, fontSize, fontFamily, foregroundColor, \" +\n \"namedStyleType, alignment, lineSpacing, spaceAbove, spaceBelow.\",\n );\n }\n\n await docs.documents.batchUpdate({\n documentId: data.documentId,\n requestBody: { requests },\n });\n\n log(\"Applied formatting to document range\", {\n documentId: data.documentId,\n startIndex,\n endIndex,\n formatsApplied,\n });\n return successResponse(\n `Applied formatting to range ${startIndex}-${endIndex}: ${formatsApplied.join(\", \")}`,\n );\n}\n", "/**\n * Color conversion utilities for Google Workspace APIs.\n *\n * Each Google API (Docs, Sheets, Slides) uses slightly different\n * color structures. These helpers provide consistent conversions.\n */\n\n/**\n * RGB color with values between 0 and 1.\n */\nexport interface RgbColor {\n red?: number;\n green?: number;\n blue?: number;\n}\n\n/**\n * RGB color with optional alpha channel for transparency.\n */\nexport interface RgbColorWithAlpha extends RgbColor {\n alpha?: number;\n}\n\n/**\n * Normalize RGB color values, defaulting undefined values to 0.\n */\nexport function toRgbColor(color: RgbColor): {\n red: number;\n green: number;\n blue: number;\n} {\n return {\n red: color.red || 0,\n green: color.green || 0,\n blue: color.blue || 0,\n };\n}\n\n/**\n * Convert to Google Docs color style format.\n * Docs wraps RGB in { color: { rgbColor: {...} } }\n */\nexport function toDocsColorStyle(color: RgbColor): {\n color: { rgbColor: { red: number; green: number; blue: number } };\n} {\n return {\n color: {\n rgbColor: toRgbColor(color),\n },\n };\n}\n\n/**\n * Convert to Google Sheets color style format.\n * Sheets uses { rgbColor: {...} } directly.\n */\nexport function toSheetsColorStyle(color: RgbColor): {\n rgbColor: { red: number; green: number; blue: number };\n} {\n return {\n rgbColor: toRgbColor(color),\n };\n}\n\n/**\n * Convert to Google Slides color style format.\n * Slides uses { rgbColor: {...} } directly (same as Sheets).\n */\nexport function toSlidesColorStyle(color: RgbColor): {\n rgbColor: { red: number; green: number; blue: number };\n} {\n return {\n rgbColor: toRgbColor(color),\n };\n}\n\n/**\n * Convert to Google Slides solid fill format.\n * Used for shape and text box backgrounds.\n */\nexport function toSlidesSolidFill(color: RgbColorWithAlpha): {\n solidFill: {\n color: { rgbColor: { red: number; green: number; blue: number } };\n alpha: number;\n };\n} {\n return {\n solidFill: {\n color: toSlidesColorStyle(color),\n alpha: color.alpha ?? 1,\n },\n };\n}\n", "import type { drive_v3, sheets_v4 } from \"googleapis\";\nimport {\n successResponse,\n structuredResponse,\n errorResponse,\n withTimeout,\n validateArgs,\n toToon,\n} from \"../utils/index.js\";\nimport { GOOGLE_MIME_TYPES, getMimeTypeSuggestion } from \"../utils/mimeTypes.js\";\nimport type { ToolResponse } from \"../utils/index.js\";\nimport {\n SheetTabsSchema,\n CreateGoogleSheetSchema,\n UpdateGoogleSheetSchema,\n GetGoogleSheetContentSchema,\n FormatGoogleSheetCellsSchema,\n MergeGoogleSheetCellsSchema,\n AddGoogleSheetConditionalFormatSchema,\n} from \"../schemas/index.js\";\nimport { resolveOptionalFolderPath, checkFileExists, convertA1ToGridRange } from \"./helpers.js\";\nimport {\n getCachedSheetMetadata,\n setCachedSheetMetadata,\n clearSheetCache,\n} from \"../utils/sheetCache.js\";\nimport { toSheetsColorStyle } from \"../utils/colors.js\";\n\nasync function getSheetInfo(\n sheets: sheets_v4.Sheets,\n spreadsheetId: string,\n range: string,\n): Promise<{ sheetId: number; a1Range: string }> {\n const sheetName = range.includes(\"!\") ? range.split(\"!\")[0] : \"Sheet1\";\n const a1Range = range.includes(\"!\") ? range.split(\"!\")[1] : range;\n\n // Check cache first\n const cached = getCachedSheetMetadata(spreadsheetId, sheetName);\n if (cached) {\n return { sheetId: cached.sheetId, a1Range };\n }\n\n // Cache miss - fetch from API\n const rangeData = await sheets.spreadsheets.get({\n spreadsheetId,\n fields: \"sheets(properties(sheetId,title))\",\n });\n\n // Cache all sheets from this spreadsheet\n const sheetsData =\n rangeData.data.sheets\n ?.filter((s) => s.properties?.title && s.properties?.sheetId !== undefined)\n .map((s) => ({\n title: s.properties!.title!,\n sheetId: s.properties!.sheetId!,\n })) || [];\n\n if (sheetsData.length > 0) {\n setCachedSheetMetadata(spreadsheetId, sheetsData);\n }\n\n const sheet = sheetsData.find((s) => s.title === sheetName);\n if (!sheet) {\n const availableSheets = sheetsData.map((s) => s.title).join(\", \");\n throw new Error(\n `Sheet \"${sheetName}\" not found. Available sheets: ${availableSheets || \"none\"}`,\n );\n }\n\n return { sheetId: sheet.sheetId, a1Range };\n}\n\nexport async function handleCreateGoogleSheet(\n drive: drive_v3.Drive,\n sheets: sheets_v4.Sheets,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(CreateGoogleSheetSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n const parentFolderId = await resolveOptionalFolderPath(\n drive,\n data.parentFolderId,\n data.parentPath,\n );\n\n // Check if spreadsheet already exists\n const existingFileId = await checkFileExists(drive, data.name, parentFolderId);\n if (existingFileId) {\n return errorResponse(\n `A spreadsheet named \"${data.name}\" already exists in this location. ` +\n `To update it, use updateGoogleSheet with spreadsheetId: ${existingFileId}`,\n );\n }\n\n // Create spreadsheet with initial sheet\n const spreadsheet = await sheets.spreadsheets.create({\n requestBody: {\n properties: { title: data.name },\n sheets: [\n {\n properties: {\n sheetId: 0,\n title: \"Sheet1\",\n gridProperties: {\n rowCount: Math.max(data.data.length, 1000),\n columnCount: Math.max(data.data[0]?.length || 0, 26),\n },\n },\n },\n ],\n },\n });\n\n await drive.files.update({\n fileId: spreadsheet.data.spreadsheetId || \"\",\n addParents: parentFolderId,\n removeParents: \"root\",\n fields: \"id, name, webViewLink\",\n supportsAllDrives: true,\n });\n\n // Now update with data\n await sheets.spreadsheets.values.update({\n spreadsheetId: spreadsheet.data.spreadsheetId!,\n range: \"Sheet1!A1\",\n valueInputOption: data.valueInputOption || \"RAW\",\n requestBody: { values: data.data },\n });\n\n return successResponse(\n `Created Google Sheet: ${data.name}\\nID: ${spreadsheet.data.spreadsheetId}`,\n );\n}\n\nexport async function handleUpdateGoogleSheet(\n sheets: sheets_v4.Sheets,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(UpdateGoogleSheetSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n await sheets.spreadsheets.values.update({\n spreadsheetId: data.spreadsheetId,\n range: data.range,\n valueInputOption: data.valueInputOption || \"RAW\",\n requestBody: { values: data.data },\n });\n\n return successResponse(`Updated Google Sheet range: ${data.range}`);\n}\n\nexport async function handleGetGoogleSheetContent(\n drive: drive_v3.Drive,\n sheets: sheets_v4.Sheets,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(GetGoogleSheetContentSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Check file type before calling Sheets API to provide helpful error messages\n const metadata = await drive.files.get({\n fileId: data.spreadsheetId,\n fields: \"mimeType,name\",\n supportsAllDrives: true,\n });\n\n const mimeType = metadata.data.mimeType;\n if (mimeType !== GOOGLE_MIME_TYPES.SPREADSHEET) {\n const fileName = metadata.data.name || data.spreadsheetId;\n const suggestion = getMimeTypeSuggestion(mimeType);\n return errorResponse(`\"${fileName}\" is not a Google Sheet (type: ${mimeType}). ${suggestion}`);\n }\n\n // If no range specified, get the first sheet name and use it as range\n let range = data.range;\n if (!range) {\n const spreadsheet = await sheets.spreadsheets.get({\n spreadsheetId: data.spreadsheetId,\n fields: \"sheets(properties(title))\",\n });\n\n const firstSheetName = spreadsheet.data.sheets?.[0]?.properties?.title || \"Sheet1\";\n range = firstSheetName;\n }\n\n const response = await withTimeout(\n sheets.spreadsheets.values.get({\n spreadsheetId: data.spreadsheetId,\n range: range,\n }),\n 30000,\n \"Get sheet content\",\n );\n\n const values = response.data.values || [];\n let content = `Content for range ${range}:\\n\\n`;\n\n if (values.length === 0) {\n content += \"(empty range)\";\n } else {\n values.forEach((row, rowIndex) => {\n content += `Row ${rowIndex + 1}: ${row.join(\", \")}\\n`;\n });\n }\n\n const rowCount = values.length;\n const columnCount = values.length > 0 ? Math.max(...values.map((row) => row.length)) : 0;\n\n return structuredResponse(content, {\n spreadsheetId: data.spreadsheetId,\n range: range,\n values: values,\n rowCount: rowCount,\n columnCount: columnCount,\n });\n}\n\n// -----------------------------------------------------------------------------\n// SHEET FORMATTING HELPERS\n// -----------------------------------------------------------------------------\n\ninterface SheetFormatOptions {\n backgroundColor?: { red?: number; green?: number; blue?: number };\n horizontalAlignment?: string;\n verticalAlignment?: string;\n wrapStrategy?: string;\n bold?: boolean;\n italic?: boolean;\n strikethrough?: boolean;\n underline?: boolean;\n fontSize?: number;\n fontFamily?: string;\n foregroundColor?: { red?: number; green?: number; blue?: number };\n numberFormat?: { pattern: string; type?: string };\n}\n\ninterface CellFormatResult {\n format: sheets_v4.Schema$CellFormat;\n fields: string[];\n appliedTypes: string[];\n}\n\nfunction buildCellFormat(data: SheetFormatOptions): CellFormatResult {\n const fields: string[] = [];\n const format: sheets_v4.Schema$CellFormat = {};\n const appliedTypes: string[] = [];\n\n if (data.backgroundColor) {\n format.backgroundColorStyle = toSheetsColorStyle(data.backgroundColor);\n fields.push(\"userEnteredFormat.backgroundColorStyle\");\n }\n if (data.horizontalAlignment) {\n format.horizontalAlignment = data.horizontalAlignment;\n fields.push(\"userEnteredFormat.horizontalAlignment\");\n }\n if (data.verticalAlignment) {\n format.verticalAlignment = data.verticalAlignment;\n fields.push(\"userEnteredFormat.verticalAlignment\");\n }\n if (data.wrapStrategy) {\n format.wrapStrategy = data.wrapStrategy;\n fields.push(\"userEnteredFormat.wrapStrategy\");\n }\n\n const textResult = buildTextFormat(data);\n if (textResult.fields.length > 0) {\n format.textFormat = textResult.format;\n fields.push(\"userEnteredFormat.textFormat(\" + textResult.fields.join(\",\") + \")\");\n appliedTypes.push(\"text\");\n }\n\n if (data.numberFormat) {\n format.numberFormat = {\n pattern: data.numberFormat.pattern,\n ...(data.numberFormat.type && { type: data.numberFormat.type }),\n };\n fields.push(\"userEnteredFormat.numberFormat\");\n appliedTypes.push(\"number\");\n }\n\n return { format, fields, appliedTypes };\n}\n\nfunction buildTextFormat(data: SheetFormatOptions): {\n format: sheets_v4.Schema$TextFormat;\n fields: string[];\n} {\n const fields: string[] = [];\n const format: sheets_v4.Schema$TextFormat = {};\n\n if (data.bold !== undefined) {\n format.bold = data.bold;\n fields.push(\"bold\");\n }\n if (data.italic !== undefined) {\n format.italic = data.italic;\n fields.push(\"italic\");\n }\n if (data.strikethrough !== undefined) {\n format.strikethrough = data.strikethrough;\n fields.push(\"strikethrough\");\n }\n if (data.underline !== undefined) {\n format.underline = data.underline;\n fields.push(\"underline\");\n }\n if (data.fontSize !== undefined) {\n format.fontSize = data.fontSize;\n fields.push(\"fontSize\");\n }\n if (data.fontFamily !== undefined) {\n format.fontFamily = data.fontFamily;\n fields.push(\"fontFamily\");\n }\n if (data.foregroundColor) {\n format.foregroundColorStyle = toSheetsColorStyle(data.foregroundColor);\n fields.push(\"foregroundColorStyle\");\n }\n\n return { format, fields };\n}\n\ninterface BorderOptions {\n style: string;\n width?: number;\n color?: { red?: number; green?: number; blue?: number };\n top?: boolean;\n bottom?: boolean;\n left?: boolean;\n right?: boolean;\n innerHorizontal?: boolean;\n innerVertical?: boolean;\n}\n\nfunction buildBordersRequest(\n gridRange: sheets_v4.Schema$GridRange,\n options: BorderOptions,\n): sheets_v4.Schema$UpdateBordersRequest {\n const border: sheets_v4.Schema$Border = {\n style: options.style,\n width: options.width || 1,\n ...(options.color && { colorStyle: toSheetsColorStyle(options.color) }),\n };\n\n const request: sheets_v4.Schema$UpdateBordersRequest = { range: gridRange };\n if (options.top !== false) request.top = border;\n if (options.bottom !== false) request.bottom = border;\n if (options.left !== false) request.left = border;\n if (options.right !== false) request.right = border;\n if (options.innerHorizontal) request.innerHorizontal = border;\n if (options.innerVertical) request.innerVertical = border;\n\n return request;\n}\n\n// -----------------------------------------------------------------------------\n// SHEET FORMATTING HANDLER\n// -----------------------------------------------------------------------------\n\nexport async function handleFormatGoogleSheetCells(\n sheets: sheets_v4.Sheets,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(FormatGoogleSheetCellsSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n let sheetInfo;\n try {\n sheetInfo = await getSheetInfo(sheets, data.spreadsheetId, data.range);\n } catch (err) {\n return errorResponse(err instanceof Error ? err.message : String(err));\n }\n\n const gridRange = convertA1ToGridRange(sheetInfo.a1Range, sheetInfo.sheetId);\n const requests: sheets_v4.Schema$Request[] = [];\n const appliedFormats: string[] = [];\n\n const cellResult = buildCellFormat(data);\n if (cellResult.fields.length > 0) {\n requests.push({\n repeatCell: {\n range: gridRange,\n cell: { userEnteredFormat: cellResult.format },\n fields: cellResult.fields.join(\",\"),\n },\n });\n appliedFormats.push(...cellResult.appliedTypes);\n if (appliedFormats.length === 0) appliedFormats.push(\"cell\");\n }\n\n if (data.borders) {\n requests.push({ updateBorders: buildBordersRequest(gridRange, data.borders) });\n appliedFormats.push(\"borders\");\n }\n\n if (requests.length === 0) {\n return errorResponse(\"No formatting options specified\");\n }\n\n await sheets.spreadsheets.batchUpdate({\n spreadsheetId: data.spreadsheetId,\n requestBody: { requests },\n });\n\n return successResponse(`Formatted cells in range ${data.range} (${appliedFormats.join(\", \")})`);\n}\n\nexport async function handleMergeGoogleSheetCells(\n sheets: sheets_v4.Sheets,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(MergeGoogleSheetCellsSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n let sheetInfo;\n try {\n sheetInfo = await getSheetInfo(sheets, data.spreadsheetId, data.range);\n } catch (err) {\n return errorResponse(err instanceof Error ? err.message : String(err));\n }\n\n const gridRange = convertA1ToGridRange(sheetInfo.a1Range, sheetInfo.sheetId);\n\n const requests: sheets_v4.Schema$Request[] = [\n {\n mergeCells: {\n range: gridRange,\n mergeType: data.mergeType,\n },\n },\n ];\n\n await sheets.spreadsheets.batchUpdate({\n spreadsheetId: data.spreadsheetId,\n requestBody: { requests },\n });\n\n return successResponse(`Merged cells in range ${data.range} with type ${data.mergeType}`);\n}\n\nexport async function handleAddGoogleSheetConditionalFormat(\n sheets: sheets_v4.Sheets,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(AddGoogleSheetConditionalFormatSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n let sheetInfo;\n try {\n sheetInfo = await getSheetInfo(sheets, data.spreadsheetId, data.range);\n } catch (err) {\n return errorResponse(err instanceof Error ? err.message : String(err));\n }\n\n const gridRange = convertA1ToGridRange(sheetInfo.a1Range, sheetInfo.sheetId);\n\n // Build condition based on type\n const booleanCondition: sheets_v4.Schema$BooleanCondition = {\n type: data.condition.type,\n values: [{ userEnteredValue: data.condition.value }],\n };\n\n const format: sheets_v4.Schema$CellFormat = {};\n if (data.format.backgroundColor) {\n format.backgroundColorStyle = toSheetsColorStyle(data.format.backgroundColor);\n }\n if (data.format.textFormat) {\n format.textFormat = {};\n if (data.format.textFormat.bold !== undefined) {\n format.textFormat.bold = data.format.textFormat.bold;\n }\n if (data.format.textFormat.foregroundColor) {\n format.textFormat.foregroundColorStyle = toSheetsColorStyle(\n data.format.textFormat.foregroundColor,\n );\n }\n }\n\n const requests: sheets_v4.Schema$Request[] = [\n {\n addConditionalFormatRule: {\n rule: {\n ranges: [gridRange],\n booleanRule: {\n condition: booleanCondition,\n format: format,\n },\n },\n index: 0,\n },\n },\n ];\n\n await sheets.spreadsheets.batchUpdate({\n spreadsheetId: data.spreadsheetId,\n requestBody: { requests },\n });\n\n return successResponse(`Added conditional formatting to range ${data.range}`);\n}\n\n/**\n * Helper function to resolve a sheet title to its sheetId.\n * Returns the sheetId if found, null otherwise.\n */\nasync function getSheetIdByTitle(\n sheets: sheets_v4.Sheets,\n spreadsheetId: string,\n title: string,\n): Promise<number | null> {\n // Check cache first\n const cached = getCachedSheetMetadata(spreadsheetId, title);\n if (cached) {\n return cached.sheetId;\n }\n\n // Fetch from API\n const response = await sheets.spreadsheets.get({\n spreadsheetId,\n fields: \"sheets(properties(sheetId,title))\",\n });\n\n const sheetsData =\n response.data.sheets\n ?.filter((s) => s.properties?.title && s.properties?.sheetId !== undefined)\n .map((s) => ({\n title: s.properties!.title!,\n sheetId: s.properties!.sheetId!,\n })) || [];\n\n // Cache all sheets\n if (sheetsData.length > 0) {\n setCachedSheetMetadata(spreadsheetId, sheetsData);\n }\n\n const sheet = sheetsData.find((s) => s.title === title);\n return sheet ? sheet.sheetId : null;\n}\n\n/**\n * Unified sheet tabs handler - list, create, delete, or rename tabs\n */\nexport async function handleSheetTabs(\n sheets: sheets_v4.Sheets,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(SheetTabsSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n switch (data.action) {\n case \"list\":\n return listSheetTabs(sheets, data.spreadsheetId);\n\n case \"create\":\n return createSheetTab(sheets, data.spreadsheetId, data.title!, data.index);\n\n case \"delete\":\n return deleteSheetTab(sheets, data.spreadsheetId, data.title!);\n\n case \"rename\":\n return renameSheetTab(sheets, data.spreadsheetId, data.currentTitle!, data.newTitle!);\n\n default:\n return errorResponse(`Unknown action: ${data.action}`);\n }\n}\n\nasync function listSheetTabs(\n sheets: sheets_v4.Sheets,\n spreadsheetId: string,\n): Promise<ToolResponse> {\n const response = await sheets.spreadsheets.get({\n spreadsheetId,\n fields:\n \"spreadsheetId,sheets(properties(sheetId,title,index,gridProperties(rowCount,columnCount)))\",\n });\n\n const tabs =\n response.data.sheets?.map((sheet) => ({\n sheetId: sheet.properties?.sheetId,\n title: sheet.properties?.title,\n index: sheet.properties?.index,\n rowCount: sheet.properties?.gridProperties?.rowCount,\n columnCount: sheet.properties?.gridProperties?.columnCount,\n })) || [];\n\n return structuredResponse(`Spreadsheet has ${tabs.length} tab(s):\\n\\n${toToon({ tabs })}`, {\n spreadsheetId,\n tabs,\n });\n}\n\nasync function createSheetTab(\n sheets: sheets_v4.Sheets,\n spreadsheetId: string,\n title: string,\n index?: number,\n): Promise<ToolResponse> {\n // Check if sheet name already exists\n const existingSheetId = await getSheetIdByTitle(sheets, spreadsheetId, title);\n if (existingSheetId !== null) {\n return errorResponse(`A sheet tab named \"${title}\" already exists in this spreadsheet.`, {\n code: \"ALREADY_EXISTS\",\n });\n }\n\n const addSheetRequest: sheets_v4.Schema$Request = {\n addSheet: {\n properties: {\n title,\n ...(index !== undefined && { index }),\n },\n },\n };\n\n const response = await sheets.spreadsheets.batchUpdate({\n spreadsheetId,\n requestBody: { requests: [addSheetRequest] },\n });\n\n clearSheetCache(spreadsheetId);\n const newSheetId = response.data.replies?.[0]?.addSheet?.properties?.sheetId;\n return successResponse(`Created new sheet tab \"${title}\" (ID: ${newSheetId})`);\n}\n\nasync function deleteSheetTab(\n sheets: sheets_v4.Sheets,\n spreadsheetId: string,\n title: string,\n): Promise<ToolResponse> {\n const sheetId = await getSheetIdByTitle(sheets, spreadsheetId, title);\n if (sheetId === null) {\n const spreadsheet = await sheets.spreadsheets.get({ spreadsheetId });\n const availableSheets =\n spreadsheet.data.sheets\n ?.map((s) => s.properties?.title)\n .filter(Boolean)\n .join(\", \") || \"none\";\n return errorResponse(`Sheet tab \"${title}\" not found. Available sheets: ${availableSheets}`);\n }\n\n try {\n await sheets.spreadsheets.batchUpdate({\n spreadsheetId,\n requestBody: { requests: [{ deleteSheet: { sheetId } }] },\n });\n } catch (error: unknown) {\n const err = error as { message?: string };\n if (err.message?.includes(\"last sheet\") || err.message?.includes(\"at least one sheet\")) {\n return errorResponse(`Cannot delete \"${title}\" - spreadsheet must have at least one sheet.`);\n }\n throw error;\n }\n\n clearSheetCache(spreadsheetId);\n return successResponse(`Deleted sheet tab \"${title}\"`);\n}\n\nasync function renameSheetTab(\n sheets: sheets_v4.Sheets,\n spreadsheetId: string,\n currentTitle: string,\n newTitle: string,\n): Promise<ToolResponse> {\n const sheetId = await getSheetIdByTitle(sheets, spreadsheetId, currentTitle);\n if (sheetId === null) {\n const spreadsheet = await sheets.spreadsheets.get({ spreadsheetId });\n const availableSheets =\n spreadsheet.data.sheets\n ?.map((s) => s.properties?.title)\n .filter(Boolean)\n .join(\", \") || \"none\";\n return errorResponse(\n `Sheet tab \"${currentTitle}\" not found. Available sheets: ${availableSheets}`,\n );\n }\n\n const existingNewId = await getSheetIdByTitle(sheets, spreadsheetId, newTitle);\n if (existingNewId !== null) {\n return errorResponse(`A sheet tab named \"${newTitle}\" already exists in this spreadsheet.`);\n }\n\n await sheets.spreadsheets.batchUpdate({\n spreadsheetId,\n requestBody: {\n requests: [\n {\n updateSheetProperties: {\n properties: { sheetId, title: newTitle },\n fields: \"title\",\n },\n },\n ],\n },\n });\n\n clearSheetCache(spreadsheetId);\n return successResponse(`Renamed sheet tab \"${currentTitle}\" to \"${newTitle}\"`);\n}\n", "/**\n * Simple in-memory cache for sheet metadata (sheetName \u2192 sheetId mapping).\n * Avoids redundant API calls when applying multiple formatting operations\n * to the same spreadsheet.\n */\n\ninterface SheetMetadata {\n sheetId: number;\n title: string;\n}\n\ninterface CacheEntry {\n sheets: Map<string, SheetMetadata>;\n timestamp: number;\n}\n\nconst TTL_MS = 60_000; // 60-second cache TTL\nconst cache = new Map<string, CacheEntry>();\n\nexport function getCachedSheetMetadata(\n spreadsheetId: string,\n sheetName: string,\n): SheetMetadata | undefined {\n const entry = cache.get(spreadsheetId);\n if (!entry) return undefined;\n\n // Check if cache is expired\n if (Date.now() - entry.timestamp > TTL_MS) {\n cache.delete(spreadsheetId);\n return undefined;\n }\n\n return entry.sheets.get(sheetName);\n}\n\nexport function setCachedSheetMetadata(\n spreadsheetId: string,\n sheets: Array<{ title: string; sheetId: number }>,\n): void {\n const sheetsMap = new Map<string, SheetMetadata>();\n for (const sheet of sheets) {\n sheetsMap.set(sheet.title, { sheetId: sheet.sheetId, title: sheet.title });\n }\n\n cache.set(spreadsheetId, {\n sheets: sheetsMap,\n timestamp: Date.now(),\n });\n}\n\nexport function clearSheetCache(spreadsheetId?: string): void {\n if (spreadsheetId) {\n cache.delete(spreadsheetId);\n } else {\n cache.clear();\n }\n}\n\nexport function getSheetCacheStats(): { size: number; entries: string[] } {\n return {\n size: cache.size,\n entries: Array.from(cache.keys()),\n };\n}\n", "import { randomUUID } from \"node:crypto\";\nimport type { drive_v3, slides_v1 } from \"googleapis\";\nimport {\n successResponse,\n structuredResponse,\n errorResponse,\n withTimeout,\n validateArgs,\n} from \"../utils/index.js\";\nimport { GOOGLE_MIME_TYPES, getMimeTypeSuggestion } from \"../utils/mimeTypes.js\";\nimport type { ToolResponse } from \"../utils/index.js\";\nimport {\n ListSlidePagesSchema,\n CreateGoogleSlidesSchema,\n UpdateGoogleSlidesSchema,\n GetGoogleSlidesContentSchema,\n CreateGoogleSlidesTextBoxSchema,\n CreateGoogleSlidesShapeSchema,\n SlidesSpeakerNotesSchema,\n FormatSlidesTextSchema,\n FormatSlidesShapeSchema,\n FormatSlideBackgroundSchema,\n} from \"../schemas/index.js\";\nimport { resolveOptionalFolderPath, checkFileExists } from \"./helpers.js\";\nimport { toSlidesColorStyle, toSlidesSolidFill } from \"../utils/colors.js\";\n\nexport async function handleCreateGoogleSlides(\n drive: drive_v3.Drive,\n slides: slides_v1.Slides,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(CreateGoogleSlidesSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n const parentFolderId = await resolveOptionalFolderPath(\n drive,\n data.parentFolderId,\n data.parentPath,\n );\n\n // Check if presentation already exists\n const existingFileId = await checkFileExists(drive, data.name, parentFolderId);\n if (existingFileId) {\n return errorResponse(\n `A presentation named \"${data.name}\" already exists in this location. ` +\n `File ID: ${existingFileId}. To modify it, you can use Google Slides directly.`,\n );\n }\n\n // API call 1: Create presentation\n const presentation = await slides.presentations.create({\n requestBody: { title: data.name },\n });\n\n // API call 2: Move to folder\n await drive.files.update({\n fileId: presentation.data.presentationId!,\n addParents: parentFolderId,\n removeParents: \"root\",\n supportsAllDrives: true,\n });\n\n // Generate all slide IDs upfront\n const slideIds = data.slides.map(() => `slide_${randomUUID().substring(0, 8)}`);\n\n // API call 3: Batch create all slides at once\n const createSlideRequests: slides_v1.Schema$Request[] = slideIds.map((slideObjectId) => ({\n createSlide: {\n objectId: slideObjectId,\n slideLayoutReference: { predefinedLayout: \"TITLE_AND_BODY\" },\n },\n }));\n\n await slides.presentations.batchUpdate({\n presentationId: presentation.data.presentationId!,\n requestBody: { requests: createSlideRequests },\n });\n\n // API call 4: Fetch all slides to get placeholder IDs\n const updatedPresentation = await slides.presentations.get({\n presentationId: presentation.data.presentationId!,\n });\n\n // Build insert text requests for all slides\n const insertTextRequests: slides_v1.Schema$Request[] = [];\n\n // Note: The first slide in the response is the default blank slide created with the presentation\n // Our custom slides start at index 1\n for (let i = 0; i < data.slides.length; i++) {\n const slide = data.slides[i];\n // Our slides start at index 1 (after the default blank slide)\n const presentationSlide = updatedPresentation.data.slides?.[i + 1];\n\n if (presentationSlide?.pageElements) {\n for (const el of presentationSlide.pageElements) {\n if (el.shape?.placeholder?.type === \"TITLE\" && el.objectId) {\n insertTextRequests.push({\n insertText: {\n objectId: el.objectId,\n text: slide.title,\n insertionIndex: 0,\n },\n });\n } else if (el.shape?.placeholder?.type === \"BODY\" && el.objectId) {\n insertTextRequests.push({\n insertText: {\n objectId: el.objectId,\n text: slide.content,\n insertionIndex: 0,\n },\n });\n }\n }\n }\n }\n\n // API call 5: Batch insert all text at once\n if (insertTextRequests.length > 0) {\n await slides.presentations.batchUpdate({\n presentationId: presentation.data.presentationId!,\n requestBody: { requests: insertTextRequests },\n });\n }\n\n return successResponse(\n `Created Google Slides presentation: ${data.name}\\n` +\n `ID: ${presentation.data.presentationId}\\n` +\n `Link: https://docs.google.com/presentation/d/${presentation.data.presentationId}`,\n );\n}\n\nexport async function handleUpdateGoogleSlides(\n slides: slides_v1.Slides,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(UpdateGoogleSlidesSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // API call 1: Get current presentation details\n const currentPresentation = await slides.presentations.get({\n presentationId: data.presentationId,\n });\n\n if (!currentPresentation.data.slides) {\n return errorResponse(\n `No slides found in presentation ${data.presentationId}. ` +\n `The presentation may be empty or inaccessible.`,\n );\n }\n\n if (data.slides.length === 0) {\n return errorResponse(\"At least one slide must be provided\");\n }\n\n // Collect all slide IDs except the first one (we'll keep it for now)\n const slideIdsToDelete = currentPresentation.data.slides\n .slice(1)\n .map((slide) => slide.objectId)\n .filter((id): id is string => id !== undefined);\n\n // Prepare all requests for a single batch update\n const requests: slides_v1.Schema$Request[] = [];\n\n // Delete all slides except the first one\n for (const slideId of slideIdsToDelete) {\n requests.push({ deleteObject: { objectId: slideId } });\n }\n\n // Clear content of the first slide\n const firstSlide = currentPresentation.data.slides[0];\n if (firstSlide?.pageElements) {\n for (const element of firstSlide.pageElements) {\n if (element.objectId && element.shape?.text) {\n requests.push({\n deleteText: {\n objectId: element.objectId,\n textRange: { type: \"ALL\" },\n },\n });\n }\n }\n }\n\n // Update the first slide with new content\n const firstSlideContent = data.slides[0];\n if (firstSlide?.pageElements) {\n let titlePlaceholderId: string | undefined;\n let bodyPlaceholderId: string | undefined;\n\n for (const element of firstSlide.pageElements) {\n if (\n element.shape?.placeholder?.type === \"TITLE\" ||\n element.shape?.placeholder?.type === \"CENTERED_TITLE\"\n ) {\n titlePlaceholderId = element.objectId || undefined;\n } else if (\n element.shape?.placeholder?.type === \"BODY\" ||\n element.shape?.placeholder?.type === \"SUBTITLE\"\n ) {\n bodyPlaceholderId = element.objectId || undefined;\n }\n }\n\n if (titlePlaceholderId) {\n requests.push({\n insertText: {\n objectId: titlePlaceholderId,\n text: firstSlideContent.title,\n insertionIndex: 0,\n },\n });\n }\n\n if (bodyPlaceholderId) {\n requests.push({\n insertText: {\n objectId: bodyPlaceholderId,\n text: firstSlideContent.content,\n insertionIndex: 0,\n },\n });\n }\n }\n\n // For additional slides, use placeholderIdMappings to set known IDs upfront\n // This avoids needing a second API call to fetch placeholder IDs\n const newSlideData: Array<{\n slideId: string;\n titleId: string;\n bodyId: string;\n }> = [];\n\n for (let i = 1; i < data.slides.length; i++) {\n const slideId = `slide_${Date.now()}_${i}`;\n const titleId = `title_${Date.now()}_${i}`;\n const bodyId = `body_${Date.now()}_${i}`;\n\n newSlideData.push({ slideId, titleId, bodyId });\n\n requests.push({\n createSlide: {\n objectId: slideId,\n slideLayoutReference: { predefinedLayout: \"TITLE_AND_BODY\" },\n placeholderIdMappings: [\n {\n layoutPlaceholder: { type: \"TITLE\" },\n objectId: titleId,\n },\n {\n layoutPlaceholder: { type: \"BODY\" },\n objectId: bodyId,\n },\n ],\n },\n });\n }\n\n // Add insertText requests for all additional slides using our pre-assigned IDs\n for (let i = 0; i < newSlideData.length; i++) {\n const slideContent = data.slides[i + 1];\n const { titleId, bodyId } = newSlideData[i];\n\n requests.push({\n insertText: {\n objectId: titleId,\n text: slideContent.title,\n insertionIndex: 0,\n },\n });\n requests.push({\n insertText: {\n objectId: bodyId,\n text: slideContent.content,\n insertionIndex: 0,\n },\n });\n }\n\n // API call 2: Execute single batch update with all operations\n await slides.presentations.batchUpdate({\n presentationId: data.presentationId,\n requestBody: { requests },\n });\n\n return successResponse(\n `Updated Google Slides presentation with ${data.slides.length} slide(s)\\n` +\n `Link: https://docs.google.com/presentation/d/${data.presentationId}`,\n );\n}\n\nexport async function handleGetGoogleSlidesContent(\n drive: drive_v3.Drive,\n slides: slides_v1.Slides,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(GetGoogleSlidesContentSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Check file type before calling Slides API to provide helpful error messages\n const metadata = await drive.files.get({\n fileId: data.presentationId,\n fields: \"mimeType,name\",\n supportsAllDrives: true,\n });\n\n const mimeType = metadata.data.mimeType;\n if (mimeType !== GOOGLE_MIME_TYPES.PRESENTATION) {\n const fileName = metadata.data.name || data.presentationId;\n const suggestion = getMimeTypeSuggestion(mimeType);\n return errorResponse(\n `\"${fileName}\" is not a Google Slides presentation (type: ${mimeType}). ${suggestion}`,\n );\n }\n\n const presentation = await withTimeout(\n slides.presentations.get({\n presentationId: data.presentationId,\n }),\n 30000,\n \"Get presentation content\",\n );\n\n if (!presentation.data.slides) {\n return errorResponse(\n `No slides found in presentation ${data.presentationId}. ` +\n `The presentation may be empty or inaccessible.`,\n );\n }\n\n let content = \"Presentation content with element IDs:\\n\\n\";\n const slidesToShow =\n data.slideIndex !== undefined\n ? [presentation.data.slides[data.slideIndex]]\n : presentation.data.slides;\n\n interface SlideElement {\n objectId: string;\n type: string;\n text?: string;\n shapeType?: string;\n }\n\n interface SlideData {\n index: number;\n objectId: string;\n elements: SlideElement[];\n }\n\n const structuredSlides: SlideData[] = [];\n\n slidesToShow.forEach((slide, index) => {\n if (!slide || !slide.objectId) return;\n\n const slideIndex = data.slideIndex ?? index;\n content += `\\nSlide ${slideIndex} (ID: ${slide.objectId}):\\n`;\n content += \"----------------------------\\n\";\n\n const slideData: SlideData = {\n index: slideIndex,\n objectId: slide.objectId,\n elements: [],\n };\n\n if (slide.pageElements) {\n slide.pageElements.forEach((element) => {\n if (!element.objectId) return;\n\n if (element.shape?.text) {\n content += ` Text Box (ID: ${element.objectId}):\\n`;\n const textElements = element.shape.text.textElements || [];\n let text = \"\";\n textElements.forEach((textElement) => {\n if (textElement.textRun?.content) {\n text += textElement.textRun.content;\n }\n });\n content += ` \"${text.trim()}\"\\n`;\n slideData.elements.push({\n objectId: element.objectId,\n type: \"textBox\",\n text: text.trim(),\n });\n } else if (element.shape) {\n content += ` Shape (ID: ${element.objectId}): ${element.shape.shapeType || \"Unknown\"}\\n`;\n slideData.elements.push({\n objectId: element.objectId,\n type: \"shape\",\n shapeType: element.shape.shapeType || undefined,\n });\n } else if (element.image) {\n content += ` Image (ID: ${element.objectId})\\n`;\n slideData.elements.push({\n objectId: element.objectId,\n type: \"image\",\n });\n } else if (element.video) {\n content += ` Video (ID: ${element.objectId})\\n`;\n slideData.elements.push({\n objectId: element.objectId,\n type: \"video\",\n });\n } else if (element.table) {\n content += ` Table (ID: ${element.objectId})\\n`;\n slideData.elements.push({\n objectId: element.objectId,\n type: \"table\",\n });\n }\n });\n }\n\n structuredSlides.push(slideData);\n });\n\n return structuredResponse(content, {\n presentationId: data.presentationId,\n title: presentation.data.title,\n slideCount: presentation.data.slides?.length || 0,\n slides: structuredSlides,\n });\n}\n\nexport async function handleCreateGoogleSlidesTextBox(\n slides: slides_v1.Slides,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(CreateGoogleSlidesTextBoxSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n const elementId = `textBox_${randomUUID().substring(0, 8)}`;\n\n const requests: slides_v1.Schema$Request[] = [\n {\n createShape: {\n objectId: elementId,\n shapeType: \"TEXT_BOX\",\n elementProperties: {\n pageObjectId: data.pageObjectId,\n size: {\n width: { magnitude: data.width, unit: \"EMU\" },\n height: { magnitude: data.height, unit: \"EMU\" },\n },\n transform: {\n scaleX: 1,\n scaleY: 1,\n translateX: data.x,\n translateY: data.y,\n unit: \"EMU\",\n },\n },\n },\n },\n {\n insertText: {\n objectId: elementId,\n text: data.text,\n insertionIndex: 0,\n },\n },\n ];\n\n // Apply optional formatting\n if (data.fontSize || data.bold || data.italic) {\n const textStyle: Record<string, unknown> = {};\n const fields: string[] = [];\n\n if (data.fontSize) {\n textStyle.fontSize = { magnitude: data.fontSize, unit: \"PT\" };\n fields.push(\"fontSize\");\n }\n\n if (data.bold !== undefined) {\n textStyle.bold = data.bold;\n fields.push(\"bold\");\n }\n\n if (data.italic !== undefined) {\n textStyle.italic = data.italic;\n fields.push(\"italic\");\n }\n\n if (fields.length > 0) {\n requests.push({\n updateTextStyle: {\n objectId: elementId,\n style: textStyle,\n fields: fields.join(\",\"),\n textRange: { type: \"ALL\" },\n },\n });\n }\n }\n\n await slides.presentations.batchUpdate({\n presentationId: data.presentationId,\n requestBody: { requests },\n });\n\n return successResponse(`Created text box with ID: ${elementId}`);\n}\n\nexport async function handleCreateGoogleSlidesShape(\n slides: slides_v1.Slides,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(CreateGoogleSlidesShapeSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n const elementId = `shape_${randomUUID().substring(0, 8)}`;\n\n const requests: slides_v1.Schema$Request[] = [\n {\n createShape: {\n objectId: elementId,\n shapeType: data.shapeType,\n elementProperties: {\n pageObjectId: data.pageObjectId,\n size: {\n width: { magnitude: data.width, unit: \"EMU\" },\n height: { magnitude: data.height, unit: \"EMU\" },\n },\n transform: {\n scaleX: 1,\n scaleY: 1,\n translateX: data.x,\n translateY: data.y,\n unit: \"EMU\",\n },\n },\n },\n },\n ];\n\n // Apply background color if specified\n if (data.backgroundColor) {\n requests.push({\n updateShapeProperties: {\n objectId: elementId,\n shapeProperties: {\n shapeBackgroundFill: {\n solidFill: {\n color: {\n rgbColor: {\n red: data.backgroundColor.red || 0,\n green: data.backgroundColor.green || 0,\n blue: data.backgroundColor.blue || 0,\n },\n },\n alpha: data.backgroundColor.alpha || 1,\n },\n },\n },\n fields: \"shapeBackgroundFill\",\n },\n });\n }\n\n await slides.presentations.batchUpdate({\n presentationId: data.presentationId,\n requestBody: { requests },\n });\n\n return successResponse(`Created ${data.shapeType} shape with ID: ${elementId}`);\n}\n\n/**\n * Unified speaker notes handler - get or update notes\n */\nexport async function handleSlidesSpeakerNotes(\n slides: slides_v1.Slides,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(SlidesSpeakerNotesSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Get the presentation to access the slide\n const presentation = await slides.presentations.get({\n presentationId: data.presentationId,\n });\n\n const slideCount = presentation.data.slides?.length || 0;\n if (!presentation.data.slides || data.slideIndex < 0 || data.slideIndex >= slideCount) {\n return errorResponse(\n `Slide index ${data.slideIndex} is invalid. Valid range: 0 to ${slideCount - 1} (presentation has ${slideCount} slides)`,\n );\n }\n\n const slide = presentation.data.slides[data.slideIndex];\n const notesObjectId = slide.slideProperties?.notesPage?.notesProperties?.speakerNotesObjectId;\n\n if (data.action === \"get\") {\n return getSpeakerNotes(slide, notesObjectId);\n } else {\n return updateSpeakerNotes(slides, data.presentationId, slide, notesObjectId, data.notes!);\n }\n}\n\nfunction getSpeakerNotes(\n slide: slides_v1.Schema$Page,\n notesObjectId: string | null | undefined,\n): ToolResponse {\n if (!notesObjectId) {\n return successResponse(\"No speaker notes found for this slide\");\n }\n\n const notesPage = slide.slideProperties?.notesPage;\n if (!notesPage || !notesPage.pageElements) {\n return successResponse(\"No speaker notes found for this slide\");\n }\n\n const speakerNotesElement = notesPage.pageElements.find(\n (element) => element.objectId === notesObjectId,\n );\n\n if (!speakerNotesElement || !speakerNotesElement.shape?.text) {\n return successResponse(\"No speaker notes found for this slide\");\n }\n\n let notesText = \"\";\n const textElements = speakerNotesElement.shape.text.textElements || [];\n textElements.forEach((textElement) => {\n if (textElement.textRun?.content) {\n notesText += textElement.textRun.content;\n }\n });\n\n return successResponse(notesText.trim() || \"No speaker notes found for this slide\");\n}\n\nasync function updateSpeakerNotes(\n slidesApi: slides_v1.Slides,\n presentationId: string,\n slide: slides_v1.Schema$Page,\n notesObjectId: string | null | undefined,\n notes: string,\n): Promise<ToolResponse> {\n if (!notesObjectId) {\n return errorResponse(\n \"This slide does not have a speaker notes object. \" +\n \"Speaker notes may need to be initialized manually in Google Slides first.\",\n );\n }\n\n const notesPage = slide.slideProperties?.notesPage;\n const speakerNotesElement = notesPage?.pageElements?.find(\n (element) => element.objectId === notesObjectId,\n );\n\n const hasExistingText = speakerNotesElement?.shape?.text?.textElements?.some(\n (el) => el.textRun?.content && el.textRun.content.trim().length > 0,\n );\n\n const requests: slides_v1.Schema$Request[] = [];\n\n if (hasExistingText) {\n requests.push({\n deleteText: {\n objectId: notesObjectId,\n textRange: { type: \"ALL\" },\n },\n });\n }\n\n requests.push({\n insertText: {\n objectId: notesObjectId,\n text: notes,\n insertionIndex: 0,\n },\n });\n\n await slidesApi.presentations.batchUpdate({\n presentationId,\n requestBody: { requests },\n });\n\n return successResponse(`Successfully updated speaker notes for slide`);\n}\n\n/**\n * Format text in a slides element (character and paragraph styling)\n */\nexport async function handleFormatSlidesText(\n slides: slides_v1.Slides,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(FormatSlidesTextSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n const requests: slides_v1.Schema$Request[] = [];\n const appliedFormats: string[] = [];\n\n // Character formatting\n const textStyle: Record<string, unknown> = {};\n const textFields: string[] = [];\n\n if (data.bold !== undefined) {\n textStyle.bold = data.bold;\n textFields.push(\"bold\");\n }\n if (data.italic !== undefined) {\n textStyle.italic = data.italic;\n textFields.push(\"italic\");\n }\n if (data.underline !== undefined) {\n textStyle.underline = data.underline;\n textFields.push(\"underline\");\n }\n if (data.strikethrough !== undefined) {\n textStyle.strikethrough = data.strikethrough;\n textFields.push(\"strikethrough\");\n }\n if (data.fontSize !== undefined) {\n textStyle.fontSize = { magnitude: data.fontSize, unit: \"PT\" };\n textFields.push(\"fontSize\");\n }\n if (data.fontFamily !== undefined) {\n textStyle.fontFamily = data.fontFamily;\n textFields.push(\"fontFamily\");\n }\n if (data.foregroundColor) {\n textStyle.foregroundColor = {\n opaqueColor: toSlidesColorStyle(data.foregroundColor),\n };\n textFields.push(\"foregroundColor\");\n }\n\n if (textFields.length > 0) {\n requests.push({\n updateTextStyle: {\n objectId: data.objectId,\n style: textStyle,\n fields: textFields.join(\",\"),\n textRange:\n data.startIndex !== undefined && data.endIndex !== undefined\n ? {\n type: \"FIXED_RANGE\",\n startIndex: data.startIndex,\n endIndex: data.endIndex,\n }\n : { type: \"ALL\" },\n },\n });\n appliedFormats.push(\"text style\");\n }\n\n // Paragraph formatting\n if (data.alignment) {\n requests.push({\n updateParagraphStyle: {\n objectId: data.objectId,\n style: { alignment: data.alignment },\n fields: \"alignment\",\n },\n });\n appliedFormats.push(\"alignment\");\n }\n\n if (data.lineSpacing !== undefined) {\n requests.push({\n updateParagraphStyle: {\n objectId: data.objectId,\n style: { lineSpacing: data.lineSpacing },\n fields: \"lineSpacing\",\n },\n });\n appliedFormats.push(\"line spacing\");\n }\n\n if (data.bulletStyle) {\n if (data.bulletStyle === \"NONE\") {\n requests.push({ deleteParagraphBullets: { objectId: data.objectId } });\n } else if (data.bulletStyle === \"NUMBERED\") {\n requests.push({\n createParagraphBullets: {\n objectId: data.objectId,\n bulletPreset: \"NUMBERED_DIGIT_ALPHA_ROMAN\",\n },\n });\n } else {\n requests.push({\n createParagraphBullets: {\n objectId: data.objectId,\n bulletPreset: `BULLET_${data.bulletStyle}_CIRCLE_SQUARE`,\n },\n });\n }\n appliedFormats.push(\"bullet style\");\n }\n\n if (requests.length === 0) {\n return errorResponse(\n \"No formatting options specified. Provide bold, italic, underline, strikethrough, \" +\n \"fontSize, fontFamily, foregroundColor, alignment, lineSpacing, or bulletStyle.\",\n );\n }\n\n await slides.presentations.batchUpdate({\n presentationId: data.presentationId,\n requestBody: { requests },\n });\n\n return successResponse(`Formatted text ${data.objectId}: ${appliedFormats.join(\", \")}`);\n}\n\n/**\n * Format shape styling (fill and outline)\n */\nexport async function handleFormatSlidesShape(\n slides: slides_v1.Slides,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(FormatSlidesShapeSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n const shapeProperties: Record<string, unknown> = {};\n const fields: string[] = [];\n const appliedFormats: string[] = [];\n\n if (data.backgroundColor) {\n shapeProperties.shapeBackgroundFill = toSlidesSolidFill(data.backgroundColor);\n fields.push(\"shapeBackgroundFill\");\n appliedFormats.push(\"background color\");\n }\n\n const outline: Record<string, unknown> = {};\n let hasOutlineChanges = false;\n\n if (data.outlineColor) {\n outline.outlineFill = {\n solidFill: {\n color: toSlidesColorStyle(data.outlineColor),\n },\n };\n hasOutlineChanges = true;\n appliedFormats.push(\"outline color\");\n }\n\n if (data.outlineWeight !== undefined) {\n outline.weight = { magnitude: data.outlineWeight, unit: \"PT\" };\n hasOutlineChanges = true;\n appliedFormats.push(\"outline weight\");\n }\n\n if (data.outlineDashStyle !== undefined) {\n outline.dashStyle = data.outlineDashStyle;\n hasOutlineChanges = true;\n appliedFormats.push(\"outline dash style\");\n }\n\n if (hasOutlineChanges) {\n shapeProperties.outline = outline;\n fields.push(\"outline\");\n }\n\n if (fields.length === 0) {\n return errorResponse(\n \"No formatting options specified. Provide backgroundColor, outlineColor, \" +\n \"outlineWeight, or outlineDashStyle.\",\n );\n }\n\n await slides.presentations.batchUpdate({\n presentationId: data.presentationId,\n requestBody: {\n requests: [\n {\n updateShapeProperties: {\n objectId: data.objectId,\n shapeProperties,\n fields: fields.join(\",\"),\n },\n },\n ],\n },\n });\n\n return successResponse(`Formatted shape ${data.objectId}: ${appliedFormats.join(\", \")}`);\n}\n\n/**\n * Set slide background color\n */\nexport async function handleFormatSlideBackground(\n slides: slides_v1.Slides,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(FormatSlideBackgroundSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n const requests = data.pageObjectIds.map((pageObjectId) => ({\n updatePageProperties: {\n objectId: pageObjectId,\n pageProperties: {\n pageBackgroundFill: toSlidesSolidFill(data.backgroundColor),\n },\n fields: \"pageBackgroundFill\",\n },\n }));\n\n await slides.presentations.batchUpdate({\n presentationId: data.presentationId,\n requestBody: { requests },\n });\n\n return successResponse(`Set background color for ${data.pageObjectIds.length} slide(s)`);\n}\n\nexport async function handleListSlidePages(\n slides: slides_v1.Slides,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(ListSlidePagesSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n const response = await slides.presentations.get({\n presentationId: data.presentationId,\n fields: \"presentationId,slides(objectId,slideProperties(layoutObjectId))\",\n });\n\n const pages =\n response.data.slides?.map((slide, index) => ({\n objectId: slide.objectId,\n index,\n pageType: \"SLIDE\" as const,\n })) || [];\n\n const pageList = pages.map((p) => `${p.index}: ${p.objectId}`).join(\"\\n\");\n\n return structuredResponse(`Presentation has ${pages.length} slide(s):\\n${pageList}`, {\n presentationId: data.presentationId,\n pages,\n });\n}\n", "import type { drive_v3, docs_v1, sheets_v4, slides_v1 } from \"googleapis\";\nimport { structuredResponse, errorResponse, validateArgs } from \"../utils/index.js\";\nimport type { ToolResponse } from \"../utils/index.js\";\nimport { CreateFileSchema, UpdateFileSchema, GetFileContentSchema } from \"../schemas/unified.js\";\nimport { resolveOptionalFolderPath, resolveFileIdFromPath } from \"./helpers.js\";\nimport {\n GOOGLE_MIME_TYPES,\n TEXT_MIME_TYPES,\n EXTENSION_TO_TYPE,\n type FileType,\n getExtension,\n} from \"../utils/mimeTypes.js\";\n\n/**\n * Infer file type from name extension or content structure\n */\nfunction inferFileType(name: string, content: unknown, explicitType?: FileType): FileType {\n // Explicit type takes precedence\n if (explicitType) return explicitType;\n\n // Check extension\n const ext = getExtension(name);\n if (EXTENSION_TO_TYPE[ext]) {\n return EXTENSION_TO_TYPE[ext];\n }\n\n // Infer from content structure\n if (Array.isArray(content)) {\n // Check if it's a 2D array (sheet data)\n if (content.length > 0 && Array.isArray(content[0])) {\n return \"sheet\";\n }\n // Check if it's slides array\n if (\n content.length > 0 &&\n typeof content[0] === \"object\" &&\n \"title\" in content[0] &&\n \"content\" in content[0]\n ) {\n return \"slides\";\n }\n }\n\n // Default to doc for string content\n return \"doc\";\n}\n\n/**\n * Get file type from MIME type\n */\nfunction getTypeFromMime(mimeType: string): FileType | \"binary\" {\n switch (mimeType) {\n case GOOGLE_MIME_TYPES.DOCUMENT:\n return \"doc\";\n case GOOGLE_MIME_TYPES.SPREADSHEET:\n return \"sheet\";\n case GOOGLE_MIME_TYPES.PRESENTATION:\n return \"slides\";\n case TEXT_MIME_TYPES.PLAIN:\n case TEXT_MIME_TYPES.MARKDOWN:\n return \"text\";\n default:\n if (mimeType.startsWith(\"text/\")) return \"text\";\n return \"binary\";\n }\n}\n\n/**\n * Smart file creation that routes to appropriate handler based on type inference.\n */\nexport async function handleCreateFile(\n drive: drive_v3.Drive,\n docs: docs_v1.Docs,\n sheets: sheets_v4.Sheets,\n slides: slides_v1.Slides,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(CreateFileSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Resolve parent folder\n const parentFolderId = await resolveOptionalFolderPath(\n drive,\n data.parentFolderId,\n data.parentPath,\n );\n\n // Infer file type\n const fileType = inferFileType(data.name, data.content, data.type);\n\n switch (fileType) {\n case \"doc\": {\n const content =\n typeof data.content === \"string\" ? data.content : JSON.stringify(data.content);\n\n // Create Google Doc\n const doc = await drive.files.create({\n requestBody: {\n name: data.name,\n mimeType: GOOGLE_MIME_TYPES.DOCUMENT,\n parents: [parentFolderId],\n },\n supportsAllDrives: true,\n });\n\n // Insert content\n if (content) {\n await docs.documents.batchUpdate({\n documentId: doc.data.id!,\n requestBody: {\n requests: [\n { insertText: { location: { index: 1 }, text: content } },\n {\n updateParagraphStyle: {\n range: { startIndex: 1, endIndex: content.length + 1 },\n paragraphStyle: { namedStyleType: \"NORMAL_TEXT\" },\n fields: \"namedStyleType\",\n },\n },\n ],\n },\n });\n }\n\n return structuredResponse(`Created Google Doc: ${data.name}\\nID: ${doc.data.id}`, {\n id: doc.data.id,\n name: data.name,\n type: \"doc\",\n mimeType: GOOGLE_MIME_TYPES.DOCUMENT,\n webViewLink: `https://docs.google.com/document/d/${doc.data.id}/edit`,\n });\n }\n\n case \"sheet\": {\n // Ensure content is 2D array\n let sheetData: string[][];\n if (Array.isArray(data.content) && Array.isArray(data.content[0])) {\n sheetData = data.content as string[][];\n } else if (typeof data.content === \"string\") {\n // Parse CSV-like string\n sheetData = data.content.split(\"\\n\").map((row) => row.split(\",\"));\n } else {\n return errorResponse(\"Sheet content must be a 2D array or CSV string\");\n }\n\n // Create spreadsheet\n const spreadsheet = await sheets.spreadsheets.create({\n requestBody: {\n properties: { title: data.name },\n sheets: [\n {\n properties: {\n sheetId: 0,\n title: \"Sheet1\",\n gridProperties: {\n rowCount: Math.max(1000, sheetData.length),\n columnCount: 26,\n },\n },\n },\n ],\n },\n });\n\n // Move to folder\n await drive.files.update({\n fileId: spreadsheet.data.spreadsheetId!,\n addParents: parentFolderId,\n removeParents: \"root\",\n supportsAllDrives: true,\n });\n\n // Populate data\n if (sheetData.length > 0) {\n await sheets.spreadsheets.values.update({\n spreadsheetId: spreadsheet.data.spreadsheetId!,\n range: \"Sheet1!A1\",\n valueInputOption: \"RAW\",\n requestBody: { values: sheetData },\n });\n }\n\n return structuredResponse(\n `Created Google Sheet: ${data.name}\\nID: ${spreadsheet.data.spreadsheetId}`,\n {\n id: spreadsheet.data.spreadsheetId,\n name: data.name,\n type: \"sheet\",\n mimeType: GOOGLE_MIME_TYPES.SPREADSHEET,\n webViewLink: spreadsheet.data.spreadsheetUrl,\n },\n );\n }\n\n case \"slides\": {\n // Ensure content is slides array\n let slidesData: Array<{ title: string; content: string }>;\n if (\n Array.isArray(data.content) &&\n data.content.length > 0 &&\n typeof data.content[0] === \"object\" &&\n !Array.isArray(data.content[0]) &&\n \"title\" in data.content[0]\n ) {\n slidesData = data.content as Array<{ title: string; content: string }>;\n } else if (typeof data.content === \"string\") {\n // Create single slide with content\n slidesData = [{ title: data.name, content: data.content }];\n } else {\n return errorResponse(\"Slides content must be an array of {title, content} objects\");\n }\n\n // Create presentation\n const presentation = await slides.presentations.create({\n requestBody: { title: data.name },\n });\n\n // Move to folder\n await drive.files.update({\n fileId: presentation.data.presentationId!,\n addParents: parentFolderId,\n removeParents: \"root\",\n supportsAllDrives: true,\n });\n\n // Add slides (simplified - would need full implementation for content)\n if (slidesData.length > 0) {\n const { randomUUID } = await import(\"node:crypto\");\n const slideIds = slidesData.map(() => `slide_${randomUUID().substring(0, 8)}`);\n\n await slides.presentations.batchUpdate({\n presentationId: presentation.data.presentationId!,\n requestBody: {\n requests: slideIds.map((id) => ({\n createSlide: {\n objectId: id,\n slideLayoutReference: { predefinedLayout: \"TITLE_AND_BODY\" },\n },\n })),\n },\n });\n }\n\n return structuredResponse(\n `Created Google Slides: ${data.name}\\nID: ${presentation.data.presentationId}`,\n {\n id: presentation.data.presentationId,\n name: data.name,\n type: \"slides\",\n mimeType: GOOGLE_MIME_TYPES.PRESENTATION,\n webViewLink: `https://docs.google.com/presentation/d/${presentation.data.presentationId}/edit`,\n },\n );\n }\n\n case \"text\": {\n const content =\n typeof data.content === \"string\" ? data.content : JSON.stringify(data.content);\n const mimeType = data.name.endsWith(\".md\") ? TEXT_MIME_TYPES.MARKDOWN : TEXT_MIME_TYPES.PLAIN;\n\n const file = await drive.files.create({\n requestBody: {\n name: data.name,\n mimeType,\n parents: [parentFolderId],\n },\n media: {\n mimeType,\n body: content,\n },\n supportsAllDrives: true,\n });\n\n return structuredResponse(`Created text file: ${data.name}\\nID: ${file.data.id}`, {\n id: file.data.id,\n name: data.name,\n type: \"text\",\n mimeType,\n webViewLink: file.data.webViewLink,\n });\n }\n }\n}\n\n/**\n * Smart file update that detects file type and routes accordingly.\n */\nexport async function handleUpdateFile(\n drive: drive_v3.Drive,\n docs: docs_v1.Docs,\n sheets: sheets_v4.Sheets,\n _slides: slides_v1.Slides,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(UpdateFileSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Resolve file ID\n const fileId = await resolveFileIdFromPath(drive, data.fileId, data.filePath);\n\n // Get file metadata to determine type\n const file = await drive.files.get({\n fileId,\n fields: \"name, mimeType\",\n supportsAllDrives: true,\n });\n\n const fileType = getTypeFromMime(file.data.mimeType!);\n\n switch (fileType) {\n case \"doc\": {\n const content =\n typeof data.content === \"string\" ? data.content : JSON.stringify(data.content);\n\n // Get current document to find end index\n const doc = await docs.documents.get({ documentId: fileId });\n const endIndex = doc.data.body?.content?.slice(-1)[0]?.endIndex || 1;\n\n // Replace all content\n await docs.documents.batchUpdate({\n documentId: fileId,\n requestBody: {\n requests: [\n {\n deleteContentRange: {\n range: { startIndex: 1, endIndex: endIndex - 1 },\n },\n },\n { insertText: { location: { index: 1 }, text: content } },\n ],\n },\n });\n\n return structuredResponse(`Updated Google Doc: ${file.data.name}`, {\n id: fileId,\n name: file.data.name,\n type: \"doc\",\n updated: true,\n });\n }\n\n case \"sheet\": {\n let sheetData: string[][];\n if (Array.isArray(data.content) && Array.isArray(data.content[0])) {\n sheetData = data.content as string[][];\n } else if (typeof data.content === \"string\") {\n sheetData = data.content.split(\"\\n\").map((row) => row.split(\",\"));\n } else {\n return errorResponse(\"Sheet content must be a 2D array or CSV string\");\n }\n\n const range = data.range || \"Sheet1!A1\";\n\n await sheets.spreadsheets.values.update({\n spreadsheetId: fileId,\n range,\n valueInputOption: \"RAW\",\n requestBody: { values: sheetData },\n });\n\n return structuredResponse(`Updated Google Sheet: ${file.data.name}`, {\n id: fileId,\n name: file.data.name,\n type: \"sheet\",\n range,\n updated: true,\n });\n }\n\n case \"slides\": {\n return errorResponse(\n \"Updating slides requires the updateGoogleSlides tool for slide-by-slide control. \" +\n \"Use updateGoogleSlides with presentationId and slides array.\",\n );\n }\n\n case \"text\": {\n const content =\n typeof data.content === \"string\" ? data.content : JSON.stringify(data.content);\n\n await drive.files.update({\n fileId,\n media: {\n mimeType: file.data.mimeType!,\n body: content,\n },\n supportsAllDrives: true,\n });\n\n return structuredResponse(`Updated text file: ${file.data.name}`, {\n id: fileId,\n name: file.data.name,\n type: \"text\",\n updated: true,\n });\n }\n\n case \"binary\":\n return errorResponse(\n `Cannot update binary file \"${file.data.name}\" (${file.data.mimeType}). ` +\n \"Use uploadFile to replace the file.\",\n );\n }\n}\n\n/**\n * Smart content retrieval that returns appropriate format based on file type.\n */\nexport async function handleGetFileContent(\n drive: drive_v3.Drive,\n docs: docs_v1.Docs,\n sheets: sheets_v4.Sheets,\n slides: slides_v1.Slides,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(GetFileContentSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n // Resolve file ID\n const fileId = await resolveFileIdFromPath(drive, data.fileId, data.filePath);\n\n // Get file metadata\n const file = await drive.files.get({\n fileId,\n fields: \"name, mimeType, modifiedTime, size\",\n supportsAllDrives: true,\n });\n\n const fileType = getTypeFromMime(file.data.mimeType!);\n\n switch (fileType) {\n case \"doc\": {\n const doc = await docs.documents.get({ documentId: fileId });\n\n // Extract text content\n let content = \"\";\n const body = doc.data.body?.content || [];\n for (const element of body) {\n if (element.paragraph?.elements) {\n for (const textElement of element.paragraph.elements) {\n if (textElement.textRun?.content) {\n content += textElement.textRun.content;\n }\n }\n }\n }\n\n return structuredResponse(content.trim(), {\n fileId,\n name: file.data.name,\n type: \"doc\",\n mimeType: file.data.mimeType,\n content: content.trim(),\n metadata: {\n modifiedTime: file.data.modifiedTime,\n title: doc.data.title,\n },\n });\n }\n\n case \"sheet\": {\n const range = data.range || \"A:ZZ\";\n\n const response = await sheets.spreadsheets.values.get({\n spreadsheetId: fileId,\n range,\n });\n\n const values = response.data.values || [];\n\n return structuredResponse(\n `Sheet: ${file.data.name}\\nRange: ${range}\\nRows: ${values.length}`,\n {\n fileId,\n name: file.data.name,\n type: \"sheet\",\n mimeType: file.data.mimeType,\n content: values,\n range: response.data.range,\n metadata: {\n modifiedTime: file.data.modifiedTime,\n rowCount: values.length,\n columnCount: values[0]?.length || 0,\n },\n },\n );\n }\n\n case \"slides\": {\n const presentation = await slides.presentations.get({\n presentationId: fileId,\n });\n\n const slideData = (presentation.data.slides || []).map((slide, index) => {\n let title = \"\";\n let content = \"\";\n\n for (const element of slide.pageElements || []) {\n if (element.shape?.text?.textElements) {\n const text = element.shape.text.textElements\n .filter((te) => te.textRun?.content)\n .map((te) => te.textRun!.content)\n .join(\"\");\n\n // First text element with content is likely the title\n if (!title && text.trim()) {\n title = text.trim();\n } else if (text.trim()) {\n content += text;\n }\n }\n }\n\n return {\n index,\n objectId: slide.objectId,\n title: title || `Slide ${index + 1}`,\n content: content.trim(),\n };\n });\n\n return structuredResponse(`Presentation: ${file.data.name}\\nSlides: ${slideData.length}`, {\n fileId,\n name: file.data.name,\n type: \"slides\",\n mimeType: file.data.mimeType,\n content: slideData,\n metadata: {\n modifiedTime: file.data.modifiedTime,\n slideCount: slideData.length,\n title: presentation.data.title,\n },\n });\n }\n\n case \"text\": {\n const response = await drive.files.get(\n { fileId, alt: \"media\", supportsAllDrives: true },\n { responseType: \"text\" },\n );\n\n const content = typeof response.data === \"string\" ? response.data : String(response.data);\n\n return structuredResponse(content, {\n fileId,\n name: file.data.name,\n type: \"text\",\n mimeType: file.data.mimeType,\n content,\n metadata: {\n modifiedTime: file.data.modifiedTime,\n size: file.data.size,\n },\n });\n }\n\n case \"binary\":\n return errorResponse(\n `Cannot read binary file \"${file.data.name}\" (${file.data.mimeType}) as text. ` +\n \"Use downloadFile to download the raw content.\",\n );\n }\n}\n", "import type { calendar_v3 } from \"googleapis\";\nimport { log, successResponse, structuredResponse, validateArgs, toToon } from \"../utils/index.js\";\nimport type { ToolResponse } from \"../utils/index.js\";\nimport {\n ListCalendarsSchema,\n ListEventsSchema,\n GetEventSchema,\n CreateEventSchema,\n UpdateEventSchema,\n DeleteEventSchema,\n FindFreeTimeSchema,\n} from \"../schemas/index.js\";\nimport { randomUUID } from \"crypto\";\n\n// Helper to format event datetime for display\nfunction formatEventTime(eventTime: calendar_v3.Schema$EventDateTime | undefined): string {\n if (!eventTime) return \"Unknown\";\n if (eventTime.date) return eventTime.date;\n if (eventTime.dateTime) {\n const date = new Date(eventTime.dateTime);\n return date.toLocaleString();\n }\n return \"Unknown\";\n}\n\nexport async function handleListCalendars(\n calendar: calendar_v3.Calendar,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(ListCalendarsSchema, args);\n if (!validation.success) return validation.response;\n const { showHidden, showDeleted } = validation.data;\n\n const response = await calendar.calendarList.list({\n showHidden,\n showDeleted,\n });\n\n const calendars = response.data.items || [];\n\n if (calendars.length === 0) {\n return structuredResponse(\"No calendars found.\", { calendars: [] });\n }\n\n const calendarData = calendars.map((cal) => ({\n id: cal.id,\n summary: cal.summary,\n description: cal.description,\n primary: cal.primary,\n accessRole: cal.accessRole,\n backgroundColor: cal.backgroundColor,\n foregroundColor: cal.foregroundColor,\n timeZone: cal.timeZone,\n }));\n\n log(\"Listed calendars\", { count: calendars.length });\n\n return structuredResponse(\n `Found ${calendars.length} calendar(s):\\n\\n${toToon({ calendars: calendarData })}`,\n { calendars: calendarData },\n );\n}\n\nexport async function handleListEvents(\n calendar: calendar_v3.Calendar,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(ListEventsSchema, args);\n if (!validation.success) return validation.response;\n const { calendarId, timeMin, timeMax, query, maxResults, pageToken, singleEvents, orderBy } =\n validation.data;\n\n const response = await calendar.events.list({\n calendarId,\n timeMin,\n timeMax,\n q: query,\n maxResults,\n pageToken,\n singleEvents,\n orderBy,\n });\n\n const events = response.data.items || [];\n\n if (events.length === 0) {\n return structuredResponse(\"No events found.\", {\n events: [],\n nextPageToken: null,\n });\n }\n\n const eventData = events.map((event) => ({\n id: event.id,\n summary: event.summary,\n description: event.description,\n location: event.location,\n start: event.start,\n end: event.end,\n status: event.status,\n htmlLink: event.htmlLink,\n hangoutLink: event.hangoutLink,\n attendees: event.attendees?.map((a) => ({\n email: a.email,\n displayName: a.displayName,\n responseStatus: a.responseStatus,\n optional: a.optional,\n })),\n organizer: event.organizer,\n creator: event.creator,\n recurringEventId: event.recurringEventId,\n }));\n\n let textResponse = `Found ${events.length} event(s):\\n\\n${toToon({ events: eventData })}`;\n if (response.data.nextPageToken) {\n textResponse += `\\n\\nMore events available. Use pageToken: ${response.data.nextPageToken}`;\n }\n\n log(\"Listed events\", { calendarId, count: events.length });\n\n return structuredResponse(textResponse, {\n events: eventData,\n nextPageToken: response.data.nextPageToken || null,\n });\n}\n\nexport async function handleGetEvent(\n calendar: calendar_v3.Calendar,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(GetEventSchema, args);\n if (!validation.success) return validation.response;\n const { calendarId, eventId } = validation.data;\n\n const response = await calendar.events.get({\n calendarId,\n eventId,\n });\n\n const event = response.data;\n\n const attendeeList =\n event.attendees && event.attendees.length > 0\n ? event.attendees.map((a) => ` - ${a.email} (${a.responseStatus || \"unknown\"})`).join(\"\\n\")\n : \" None\";\n\n const meetLink = event.hangoutLink ? `\\nGoogle Meet: ${event.hangoutLink}` : \"\";\n\n const textResponse = [\n `Event: ${event.summary || \"(No title)\"}`,\n `ID: ${event.id}`,\n `Status: ${event.status}`,\n `Start: ${formatEventTime(event.start)}`,\n `End: ${formatEventTime(event.end)}`,\n event.location ? `Location: ${event.location}` : null,\n event.description ? `Description: ${event.description}` : null,\n meetLink,\n `\\nAttendees:\\n${attendeeList}`,\n `\\nOrganizer: ${event.organizer?.email || \"Unknown\"}`,\n `Link: ${event.htmlLink}`,\n ]\n .filter(Boolean)\n .join(\"\\n\");\n\n log(\"Retrieved event\", { calendarId, eventId });\n\n return structuredResponse(textResponse, {\n id: event.id,\n summary: event.summary,\n description: event.description,\n location: event.location,\n start: event.start,\n end: event.end,\n status: event.status,\n htmlLink: event.htmlLink,\n hangoutLink: event.hangoutLink,\n attendees: event.attendees?.map((a) => ({\n email: a.email,\n displayName: a.displayName,\n responseStatus: a.responseStatus,\n optional: a.optional,\n organizer: a.organizer,\n self: a.self,\n })),\n organizer: event.organizer,\n creator: event.creator,\n created: event.created,\n updated: event.updated,\n recurrence: event.recurrence,\n recurringEventId: event.recurringEventId,\n reminders: event.reminders,\n conferenceData: event.conferenceData,\n });\n}\n\nexport async function handleCreateEvent(\n calendar: calendar_v3.Calendar,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(CreateEventSchema, args);\n if (!validation.success) return validation.response;\n const {\n calendarId,\n summary,\n description,\n location,\n start,\n end,\n attendees,\n addGoogleMeet,\n reminders,\n colorId,\n recurrence,\n sendUpdates,\n } = validation.data;\n\n // Build the event request body\n const eventBody: calendar_v3.Schema$Event = {\n summary,\n description,\n location,\n start: {\n dateTime: start.dateTime,\n date: start.date,\n timeZone: start.timeZone,\n },\n end: {\n dateTime: end.dateTime,\n date: end.date,\n timeZone: end.timeZone,\n },\n colorId,\n recurrence,\n };\n\n // Add attendees if provided\n if (attendees && attendees.length > 0) {\n eventBody.attendees = attendees.map((a) => ({\n email: a.email,\n displayName: a.displayName,\n optional: a.optional,\n }));\n }\n\n // Add Google Meet conference if requested\n if (addGoogleMeet) {\n eventBody.conferenceData = {\n createRequest: {\n requestId: randomUUID(),\n conferenceSolutionKey: { type: \"hangoutsMeet\" },\n },\n };\n }\n\n // Add custom reminders if provided\n if (reminders && reminders.length > 0) {\n eventBody.reminders = {\n useDefault: false,\n overrides: reminders.map((r) => ({\n method: r.method,\n minutes: r.minutes,\n })),\n };\n }\n\n const response = await calendar.events.insert({\n calendarId,\n requestBody: eventBody,\n conferenceDataVersion: addGoogleMeet ? 1 : undefined,\n sendUpdates,\n });\n\n const event = response.data;\n const meetLink = event.hangoutLink ? `\\nGoogle Meet: ${event.hangoutLink}` : \"\";\n\n log(\"Created event\", { calendarId, eventId: event.id });\n\n return structuredResponse(\n `Created event: ${event.summary}\\nID: ${event.id}\\nLink: ${event.htmlLink}${meetLink}`,\n {\n id: event.id,\n summary: event.summary,\n start: event.start,\n end: event.end,\n htmlLink: event.htmlLink,\n hangoutLink: event.hangoutLink,\n status: event.status,\n },\n );\n}\n\nexport async function handleUpdateEvent(\n calendar: calendar_v3.Calendar,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(UpdateEventSchema, args);\n if (!validation.success) return validation.response;\n const {\n calendarId,\n eventId,\n summary,\n description,\n location,\n start,\n end,\n attendees,\n addGoogleMeet,\n reminders,\n colorId,\n sendUpdates,\n } = validation.data;\n\n // First get the existing event\n const existingEvent = await calendar.events.get({\n calendarId,\n eventId,\n });\n\n // Build update body, preserving existing values for unspecified fields\n const eventBody: calendar_v3.Schema$Event = {\n ...existingEvent.data,\n summary: summary ?? existingEvent.data.summary,\n description: description ?? existingEvent.data.description,\n location: location ?? existingEvent.data.location,\n colorId: colorId ?? existingEvent.data.colorId,\n };\n\n // Update start/end if provided\n if (start) {\n eventBody.start = {\n dateTime: start.dateTime,\n date: start.date,\n timeZone: start.timeZone,\n };\n }\n if (end) {\n eventBody.end = {\n dateTime: end.dateTime,\n date: end.date,\n timeZone: end.timeZone,\n };\n }\n\n // Update attendees if provided\n if (attendees !== undefined) {\n eventBody.attendees = attendees.map((a) => ({\n email: a.email,\n displayName: a.displayName,\n optional: a.optional,\n }));\n }\n\n // Add Google Meet if requested and not already present\n let conferenceDataVersion: number | undefined;\n if (addGoogleMeet && !existingEvent.data.hangoutLink) {\n eventBody.conferenceData = {\n createRequest: {\n requestId: randomUUID(),\n conferenceSolutionKey: { type: \"hangoutsMeet\" },\n },\n };\n conferenceDataVersion = 1;\n }\n\n // Update reminders if provided\n if (reminders !== undefined) {\n eventBody.reminders = {\n useDefault: false,\n overrides: reminders.map((r) => ({\n method: r.method,\n minutes: r.minutes,\n })),\n };\n }\n\n const response = await calendar.events.update({\n calendarId,\n eventId,\n requestBody: eventBody,\n conferenceDataVersion,\n sendUpdates,\n });\n\n const event = response.data;\n const meetLink = event.hangoutLink ? `\\nGoogle Meet: ${event.hangoutLink}` : \"\";\n\n log(\"Updated event\", { calendarId, eventId });\n\n return structuredResponse(\n `Updated event: ${event.summary}\\nID: ${event.id}\\nLink: ${event.htmlLink}${meetLink}`,\n {\n id: event.id,\n summary: event.summary,\n start: event.start,\n end: event.end,\n htmlLink: event.htmlLink,\n hangoutLink: event.hangoutLink,\n status: event.status,\n },\n );\n}\n\nexport async function handleDeleteEvent(\n calendar: calendar_v3.Calendar,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(DeleteEventSchema, args);\n if (!validation.success) return validation.response;\n const { calendarId, eventId, sendUpdates } = validation.data;\n\n // Get event info before deletion for the response\n const existingEvent = await calendar.events.get({\n calendarId,\n eventId,\n });\n\n const eventSummary = existingEvent.data.summary || \"(No title)\";\n\n await calendar.events.delete({\n calendarId,\n eventId,\n sendUpdates,\n });\n\n log(\"Deleted event\", { calendarId, eventId });\n\n return successResponse(`Deleted event: ${eventSummary} (ID: ${eventId})`);\n}\n\nexport async function handleFindFreeTime(\n calendar: calendar_v3.Calendar,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(FindFreeTimeSchema, args);\n if (!validation.success) return validation.response;\n const { calendarIds, timeMin, timeMax, duration, timeZone } = validation.data;\n\n // Use the freebusy API to get busy times\n const response = await calendar.freebusy.query({\n requestBody: {\n timeMin,\n timeMax,\n timeZone,\n items: calendarIds.map((id) => ({ id })),\n },\n });\n\n const calendarsData = response.data.calendars || {};\n\n // Collect all busy periods across all calendars\n const busyPeriods: Array<{ start: Date; end: Date }> = [];\n\n for (const calId of calendarIds) {\n const calData = calendarsData[calId];\n if (calData?.busy) {\n for (const busy of calData.busy) {\n if (busy.start && busy.end) {\n busyPeriods.push({\n start: new Date(busy.start),\n end: new Date(busy.end),\n });\n }\n }\n }\n }\n\n // Sort busy periods by start time\n busyPeriods.sort((a, b) => a.start.getTime() - b.start.getTime());\n\n // Merge overlapping busy periods\n const mergedBusy: Array<{ start: Date; end: Date }> = [];\n for (const period of busyPeriods) {\n if (mergedBusy.length === 0) {\n mergedBusy.push(period);\n } else {\n const last = mergedBusy[mergedBusy.length - 1];\n if (period.start <= last.end) {\n // Overlapping or adjacent, extend the end\n last.end = new Date(Math.max(last.end.getTime(), period.end.getTime()));\n } else {\n mergedBusy.push(period);\n }\n }\n }\n\n // Find free slots\n const freeSlots: Array<{ start: string; end: string; durationMinutes: number }> = [];\n const rangeStart = new Date(timeMin);\n const rangeEnd = new Date(timeMax);\n const durationMs = duration * 60 * 1000;\n\n let currentTime = rangeStart;\n\n for (const busy of mergedBusy) {\n // Check if there's a gap before this busy period\n if (busy.start > currentTime) {\n const gapDuration = busy.start.getTime() - currentTime.getTime();\n if (gapDuration >= durationMs) {\n freeSlots.push({\n start: currentTime.toISOString(),\n end: busy.start.toISOString(),\n durationMinutes: Math.floor(gapDuration / 60000),\n });\n }\n }\n // Move current time to end of busy period\n currentTime = new Date(Math.max(currentTime.getTime(), busy.end.getTime()));\n }\n\n // Check for free time after last busy period\n if (currentTime < rangeEnd) {\n const gapDuration = rangeEnd.getTime() - currentTime.getTime();\n if (gapDuration >= durationMs) {\n freeSlots.push({\n start: currentTime.toISOString(),\n end: rangeEnd.toISOString(),\n durationMinutes: Math.floor(gapDuration / 60000),\n });\n }\n }\n\n if (freeSlots.length === 0) {\n return structuredResponse(\n `No free slots of ${duration} minutes found in the specified range.`,\n {\n freeSlots: [],\n busyPeriods: mergedBusy.map((p) => ({\n start: p.start.toISOString(),\n end: p.end.toISOString(),\n })),\n },\n );\n }\n\n const formattedSlots = freeSlots\n .map((slot) => {\n const start = new Date(slot.start);\n const end = new Date(slot.end);\n return `- ${start.toLocaleString()} to ${end.toLocaleString()} (${slot.durationMinutes} min)`;\n })\n .join(\"\\n\");\n\n log(\"Found free time slots\", { count: freeSlots.length });\n\n return structuredResponse(\n `Found ${freeSlots.length} free slot(s) of at least ${duration} minutes:\\n\\n${formattedSlots}`,\n {\n freeSlots,\n busyPeriods: mergedBusy.map((p) => ({\n start: p.start.toISOString(),\n end: p.end.toISOString(),\n })),\n },\n );\n}\n", "import type { gmail_v1 } from \"googleapis\";\nimport {\n log,\n successResponse,\n structuredResponse,\n errorResponse,\n validateArgs,\n buildMimeMessage,\n parseEmailHeaders,\n decodeBase64Url,\n truncateResponse,\n toToon,\n} from \"../utils/index.js\";\nimport type { ToolResponse } from \"../utils/index.js\";\nimport {\n SendEmailSchema,\n DraftEmailSchema,\n ReadEmailSchema,\n SearchEmailsSchema,\n DeleteEmailSchema,\n ModifyEmailSchema,\n DownloadAttachmentSchema,\n CreateLabelSchema,\n UpdateLabelSchema,\n DeleteLabelSchema,\n ListLabelsSchema,\n GetOrCreateLabelSchema,\n CreateFilterSchema,\n ListFiltersSchema,\n DeleteFilterSchema,\n} from \"../schemas/index.js\";\nimport * as fs from \"fs/promises\";\nimport * as path from \"path\";\n\n// System labels that cannot be deleted\nconst SYSTEM_LABELS = new Set([\n \"INBOX\",\n \"SPAM\",\n \"TRASH\",\n \"UNREAD\",\n \"STARRED\",\n \"IMPORTANT\",\n \"SENT\",\n \"DRAFT\",\n \"CATEGORY_PERSONAL\",\n \"CATEGORY_SOCIAL\",\n \"CATEGORY_PROMOTIONS\",\n \"CATEGORY_UPDATES\",\n \"CATEGORY_FORUMS\",\n]);\n\n// Gmail thread IDs are 16-character hex strings\nconst THREAD_ID_PATTERN = /^[0-9a-f]{16}$/i;\n\ntype FailureCategory =\n | \"INVALID_FORMAT\"\n | \"NOT_FOUND\"\n | \"PERMISSION_DENIED\"\n | \"RATE_LIMITED\"\n | \"UNKNOWN\";\n\ninterface BatchFailure {\n threadId: string;\n category: FailureCategory;\n error: string;\n}\n\nconst CATEGORY_SUGGESTIONS: Record<FailureCategory, string> = {\n INVALID_FORMAT: \"Use search_emails to get valid thread IDs\",\n NOT_FOUND: \"Thread may have been deleted. Use search_emails to refresh\",\n PERMISSION_DENIED: \"You don't have access to this thread\",\n RATE_LIMITED: \"Too many requests. Wait and retry with smaller batches\",\n UNKNOWN: \"Check the thread ID and try again\",\n};\n\nfunction isValidThreadIdFormat(id: string): boolean {\n return THREAD_ID_PATTERN.test(id);\n}\n\nfunction categorizeError(errorMessage: string): FailureCategory {\n const msg = errorMessage.toLowerCase();\n if (msg.includes(\"invalid id\") || msg.includes(\"invalid value\")) return \"INVALID_FORMAT\";\n if (msg.includes(\"not found\")) return \"NOT_FOUND\";\n if (msg.includes(\"permission\") || msg.includes(\"forbidden\")) return \"PERMISSION_DENIED\";\n if (msg.includes(\"rate\") || msg.includes(\"quota\")) return \"RATE_LIMITED\";\n return \"UNKNOWN\";\n}\n\n// Helper to extract email body from message parts\nfunction extractEmailBody(payload: gmail_v1.Schema$MessagePart | undefined): {\n text: string;\n html: string;\n} {\n if (!payload) return { text: \"\", html: \"\" };\n\n const result = { text: \"\", html: \"\" };\n\n function processpart(part: gmail_v1.Schema$MessagePart) {\n if (part.mimeType === \"text/plain\" && part.body?.data) {\n result.text = decodeBase64Url(part.body.data);\n } else if (part.mimeType === \"text/html\" && part.body?.data) {\n result.html = decodeBase64Url(part.body.data);\n } else if (part.parts) {\n for (const subPart of part.parts) {\n processpart(subPart);\n }\n }\n }\n\n if (payload.body?.data) {\n if (payload.mimeType === \"text/html\") {\n result.html = decodeBase64Url(payload.body.data);\n } else {\n result.text = decodeBase64Url(payload.body.data);\n }\n }\n\n if (payload.parts) {\n for (const part of payload.parts) {\n processpart(part);\n }\n }\n\n return result;\n}\n\n// Helper to extract attachments info\nfunction extractAttachments(\n payload: gmail_v1.Schema$MessagePart | undefined,\n): Array<{ id: string; filename: string; mimeType: string; size: number }> {\n const attachments: Array<{ id: string; filename: string; mimeType: string; size: number }> = [];\n\n function processPart(part: gmail_v1.Schema$MessagePart) {\n if (part.filename && part.body?.attachmentId) {\n attachments.push({\n id: part.body.attachmentId,\n filename: part.filename,\n mimeType: part.mimeType || \"application/octet-stream\",\n size: part.body.size || 0,\n });\n }\n if (part.parts) {\n for (const subPart of part.parts) {\n processPart(subPart);\n }\n }\n }\n\n if (payload?.parts) {\n for (const part of payload.parts) {\n processPart(part);\n }\n }\n\n return attachments;\n}\n\n// ============================================================================\n// Core Email Operations\n// ============================================================================\n\nexport async function handleSendEmail(gmail: gmail_v1.Gmail, args: unknown): Promise<ToolResponse> {\n const validation = validateArgs(SendEmailSchema, args);\n if (!validation.success) return validation.response;\n const { to, subject, body, html, cc, bcc, replyTo, attachments, threadId, inReplyTo } =\n validation.data;\n\n const raw = buildMimeMessage({\n to,\n subject,\n body,\n html,\n cc,\n bcc,\n replyTo,\n attachments,\n inReplyTo,\n });\n\n const response = await gmail.users.messages.send({\n userId: \"me\",\n requestBody: {\n raw,\n threadId,\n },\n });\n\n log(\"Sent email\", { messageId: response.data.id, threadId: response.data.threadId });\n\n return structuredResponse(\n `Email sent successfully.\\nMessage ID: ${response.data.id}\\nThread ID: ${response.data.threadId}`,\n {\n id: response.data.id,\n threadId: response.data.threadId,\n labelIds: response.data.labelIds,\n },\n );\n}\n\nexport async function handleDraftEmail(\n gmail: gmail_v1.Gmail,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(DraftEmailSchema, args);\n if (!validation.success) return validation.response;\n const { to, subject, body, html, cc, bcc, replyTo, attachments, threadId } = validation.data;\n\n const raw = buildMimeMessage({\n to: to || [],\n subject: subject || \"\",\n body: body || \"\",\n html,\n cc,\n bcc,\n replyTo,\n attachments,\n });\n\n const response = await gmail.users.drafts.create({\n userId: \"me\",\n requestBody: {\n message: {\n raw,\n threadId,\n },\n },\n });\n\n log(\"Created draft\", { draftId: response.data.id });\n\n return structuredResponse(\n `Draft created successfully.\\nDraft ID: ${response.data.id}\\nMessage ID: ${response.data.message?.id}`,\n {\n id: response.data.id,\n messageId: response.data.message?.id,\n threadId: response.data.message?.threadId,\n },\n );\n}\n\nexport async function handleReadEmail(gmail: gmail_v1.Gmail, args: unknown): Promise<ToolResponse> {\n const validation = validateArgs(ReadEmailSchema, args);\n if (!validation.success) return validation.response;\n const { messageId, format, contentFormat } = validation.data;\n\n const response = await gmail.users.messages.get({\n userId: \"me\",\n id: messageId,\n format,\n });\n\n const message = response.data;\n const headers = parseEmailHeaders(message.payload?.headers || []);\n const attachments = extractAttachments(message.payload);\n\n // Extract body based on contentFormat\n let text = \"\";\n let html = \"\";\n if (contentFormat !== \"headers\") {\n const body = extractEmailBody(message.payload);\n text = body.text;\n html = contentFormat === \"full\" ? body.html : \"\";\n }\n\n // Build text output based on contentFormat\n const textOutputParts = [\n `From: ${headers.from || \"Unknown\"}`,\n `To: ${headers.to || \"Unknown\"}`,\n headers.cc ? `Cc: ${headers.cc}` : null,\n `Subject: ${headers.subject || \"(No subject)\"}`,\n `Date: ${headers.date || \"Unknown\"}`,\n `Labels: ${message.labelIds?.join(\", \") || \"None\"}`,\n attachments.length > 0\n ? `Attachments: ${attachments.map((a) => `${a.filename} (${a.size} bytes)`).join(\", \")}`\n : null,\n ];\n\n // Only include body section if contentFormat is not \"headers\"\n if (contentFormat !== \"headers\") {\n textOutputParts.push(\"\", \"--- Body ---\", text || html || \"(No content)\");\n }\n\n const textOutput = textOutputParts.filter(Boolean).join(\"\\n\");\n const { content: truncatedContent, truncated } = truncateResponse(textOutput);\n\n log(\"Read email\", { messageId, contentFormat, truncated });\n\n // Build response body based on contentFormat\n const responseBody =\n contentFormat === \"headers\" ? undefined : contentFormat === \"text\" ? { text } : { text, html };\n\n return structuredResponse(truncatedContent, {\n id: message.id,\n threadId: message.threadId,\n labelIds: message.labelIds,\n snippet: message.snippet,\n headers,\n body: responseBody,\n attachments,\n internalDate: message.internalDate,\n sizeEstimate: message.sizeEstimate,\n truncated,\n });\n}\n\nexport async function handleSearchEmails(\n gmail: gmail_v1.Gmail,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(SearchEmailsSchema, args);\n if (!validation.success) return validation.response;\n const { query, maxResults, pageToken, labelIds, includeSpamTrash } = validation.data;\n\n const response = await gmail.users.messages.list({\n userId: \"me\",\n q: query,\n maxResults,\n pageToken,\n labelIds,\n includeSpamTrash,\n });\n\n const messages = response.data.messages || [];\n\n if (messages.length === 0) {\n return structuredResponse(`No emails found matching: ${query}`, {\n messages: [],\n nextPageToken: null,\n resultSizeEstimate: 0,\n });\n }\n\n // Fetch basic metadata for each message\n const messageDetails = await Promise.all(\n messages.slice(0, 50).map(async (msg) => {\n const detail = await gmail.users.messages.get({\n userId: \"me\",\n id: msg.id!,\n format: \"metadata\",\n metadataHeaders: [\"From\", \"To\", \"Subject\", \"Date\"],\n });\n const headers = parseEmailHeaders(detail.data.payload?.headers || []);\n return {\n id: detail.data.id,\n threadId: detail.data.threadId,\n snippet: detail.data.snippet,\n from: headers.from,\n to: headers.to,\n subject: headers.subject,\n date: headers.date,\n labelIds: detail.data.labelIds,\n };\n }),\n );\n\n let textResponse = `Found ${response.data.resultSizeEstimate} email(s):\\n\\n${toToon({ messages: messageDetails })}`;\n if (response.data.nextPageToken) {\n textResponse += `\\n\\nMore results available. Use pageToken: ${response.data.nextPageToken}`;\n }\n\n log(\"Searched emails\", { query, count: messages.length });\n\n return structuredResponse(textResponse, {\n messages: messageDetails,\n nextPageToken: response.data.nextPageToken || null,\n resultSizeEstimate: response.data.resultSizeEstimate,\n });\n}\n\nexport async function handleDeleteEmail(\n gmail: gmail_v1.Gmail,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(DeleteEmailSchema, args);\n if (!validation.success) return validation.response;\n const { messageId } = validation.data;\n\n // Normalize to array for uniform handling\n const messageIds = Array.isArray(messageId) ? messageId : [messageId];\n\n if (messageIds.length === 1) {\n // Single delete\n await gmail.users.messages.delete({\n userId: \"me\",\n id: messageIds[0],\n });\n log(\"Deleted email\", { messageId: messageIds[0] });\n return successResponse(`Email ${messageIds[0]} permanently deleted.`);\n }\n\n // Batch delete\n try {\n await gmail.users.messages.batchDelete({\n userId: \"me\",\n requestBody: { ids: messageIds },\n });\n } catch {\n // Batch API may not be available, fall back to individual deletes\n const results = await Promise.allSettled(\n messageIds.map((id) =>\n gmail.users.messages.delete({\n userId: \"me\",\n id,\n }),\n ),\n );\n\n const succeeded = results.filter((r) => r.status === \"fulfilled\").length;\n const failed = results.filter((r) => r.status === \"rejected\").length;\n\n if (failed > 0) {\n return structuredResponse(`Partially completed: ${succeeded} deleted, ${failed} failed.`, {\n succeeded,\n failed,\n total: messageIds.length,\n });\n }\n }\n\n log(\"Deleted emails (batch)\", { count: messageIds.length });\n return successResponse(`Successfully deleted ${messageIds.length} email(s).`);\n}\n\nexport async function handleModifyEmail(\n gmail: gmail_v1.Gmail,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(ModifyEmailSchema, args);\n if (!validation.success) return validation.response;\n const { threadId, addLabelIds, removeLabelIds } = validation.data;\n\n // Normalize to array for uniform handling\n const ids = Array.isArray(threadId) ? threadId : [threadId];\n\n if (ids.length === 1) {\n const response = await gmail.users.threads.modify({\n userId: \"me\",\n id: ids[0],\n requestBody: { addLabelIds, removeLabelIds },\n });\n\n log(\"Modified thread labels\", { threadId: ids[0], addLabelIds, removeLabelIds });\n\n const messageCount = response.data.messages?.length || 0;\n return structuredResponse(\n `Thread ${ids[0]} labels updated (${messageCount} message(s) affected).\\n` +\n `Current labels: ${response.data.messages?.[0]?.labelIds?.join(\", \") || \"None\"}`,\n {\n id: response.data.id,\n historyId: response.data.historyId,\n messageCount,\n labelIds: response.data.messages?.[0]?.labelIds,\n },\n );\n }\n\n // Pre-filter invalid IDs before making any API calls\n const validIds = ids.filter(isValidThreadIdFormat);\n const invalidIds = ids.filter((id) => !isValidThreadIdFormat(id));\n\n // Create failures for invalid IDs without API calls\n const formatFailures: BatchFailure[] = invalidIds.map((id) => ({\n threadId: id,\n category: \"INVALID_FORMAT\" as const,\n error: \"Invalid thread ID format\",\n }));\n\n // Only call API for valid IDs\n const results = await Promise.allSettled(\n validIds.map((id) =>\n gmail.users.threads.modify({\n userId: \"me\",\n id,\n requestBody: { addLabelIds, removeLabelIds },\n }),\n ),\n );\n\n const apiSucceeded = results.filter((r) => r.status === \"fulfilled\").length;\n const apiFailures: BatchFailure[] = results\n .map((r, i) => ({ id: validIds[i], result: r }))\n .filter(\n (item): item is { id: string; result: PromiseRejectedResult } =>\n item.result.status === \"rejected\",\n )\n .map((item) => {\n const errorMsg = item.result.reason?.message || String(item.result.reason) || \"Unknown error\";\n return {\n threadId: item.id,\n category: categorizeError(errorMsg),\n error: errorMsg,\n };\n });\n\n const allFailures = [...formatFailures, ...apiFailures];\n const succeeded = apiSucceeded;\n\n log(\"Batch modified threads\", {\n count: ids.length,\n succeeded,\n failed: allFailures.length,\n preFiltered: invalidIds.length,\n addLabelIds,\n removeLabelIds,\n });\n\n if (allFailures.length > 0) {\n // Group failures by category\n const failuresByCategory = allFailures.reduce(\n (acc, f) => {\n if (!acc[f.category]) acc[f.category] = [];\n acc[f.category].push(f.threadId);\n return acc;\n },\n {} as Record<FailureCategory, string[]>,\n );\n\n // Build categorized failure text\n const categoryLines = (Object.entries(failuresByCategory) as [FailureCategory, string[]][])\n .map(([category, threadIds]) => {\n const suggestion = CATEGORY_SUGGESTIONS[category];\n const idList = threadIds.slice(0, 5).join(\", \");\n const moreText = threadIds.length > 5 ? ` (+${threadIds.length - 5} more)` : \"\";\n return `- ${category} (${threadIds.length}): ${suggestion}\\n ${idList}${moreText}`;\n })\n .join(\"\\n\");\n\n return structuredResponse(\n `Partially completed: ${succeeded} thread(s) modified, ${allFailures.length} failed.` +\n (addLabelIds ? `\\nAdded labels: ${addLabelIds.join(\", \")}` : \"\") +\n (removeLabelIds ? `\\nRemoved labels: ${removeLabelIds.join(\", \")}` : \"\") +\n `\\n\\nFailures:\\n${categoryLines}`,\n { succeeded, failed: allFailures.length, total: ids.length, failuresByCategory },\n );\n }\n\n return successResponse(\n `Successfully modified labels for ${ids.length} thread(s).` +\n (addLabelIds ? `\\nAdded labels: ${addLabelIds.join(\", \")}` : \"\") +\n (removeLabelIds ? `\\nRemoved labels: ${removeLabelIds.join(\", \")}` : \"\"),\n );\n}\n\nexport async function handleDownloadAttachment(\n gmail: gmail_v1.Gmail,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(DownloadAttachmentSchema, args);\n if (!validation.success) return validation.response;\n const { messageId, attachmentId, filename, outputPath } = validation.data;\n\n // Get the attachment\n const response = await gmail.users.messages.attachments.get({\n userId: \"me\",\n messageId,\n id: attachmentId,\n });\n\n if (!response.data.data) {\n return errorResponse(\"Attachment data not found\", { code: \"NOT_FOUND\" });\n }\n\n // Decode base64url data\n const data = Buffer.from(response.data.data.replace(/-/g, \"+\").replace(/_/g, \"/\"), \"base64\");\n\n // Determine output filename\n const outputFilename = filename || `attachment_${attachmentId}`;\n const outputDir = outputPath || process.cwd();\n const fullPath = path.join(outputDir, outputFilename);\n\n // Write to file\n await fs.writeFile(fullPath, data);\n\n log(\"Downloaded attachment\", { messageId, attachmentId, path: fullPath });\n\n return structuredResponse(\n `Attachment downloaded successfully.\\nSaved to: ${fullPath}\\nSize: ${data.length} bytes`,\n {\n path: fullPath,\n size: data.length,\n messageId,\n attachmentId,\n },\n );\n}\n\n// ============================================================================\n// Label Management\n// ============================================================================\n\nexport async function handleCreateLabel(\n gmail: gmail_v1.Gmail,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(CreateLabelSchema, args);\n if (!validation.success) return validation.response;\n const { name, messageListVisibility, labelListVisibility, backgroundColor, textColor } =\n validation.data;\n\n const response = await gmail.users.labels.create({\n userId: \"me\",\n requestBody: {\n name,\n messageListVisibility,\n labelListVisibility,\n color:\n backgroundColor || textColor\n ? {\n backgroundColor,\n textColor,\n }\n : undefined,\n },\n });\n\n log(\"Created label\", { labelId: response.data.id, name });\n\n return structuredResponse(`Label \"${name}\" created successfully.\\nID: ${response.data.id}`, {\n id: response.data.id,\n name: response.data.name,\n type: response.data.type,\n messageListVisibility: response.data.messageListVisibility,\n labelListVisibility: response.data.labelListVisibility,\n color: response.data.color,\n });\n}\n\nexport async function handleUpdateLabel(\n gmail: gmail_v1.Gmail,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(UpdateLabelSchema, args);\n if (!validation.success) return validation.response;\n const { labelId, name, messageListVisibility, labelListVisibility, backgroundColor, textColor } =\n validation.data;\n\n const response = await gmail.users.labels.patch({\n userId: \"me\",\n id: labelId,\n requestBody: {\n name,\n messageListVisibility,\n labelListVisibility,\n color:\n backgroundColor || textColor\n ? {\n backgroundColor,\n textColor,\n }\n : undefined,\n },\n });\n\n log(\"Updated label\", { labelId, name });\n\n return structuredResponse(`Label updated successfully.`, {\n id: response.data.id,\n name: response.data.name,\n type: response.data.type,\n messageListVisibility: response.data.messageListVisibility,\n labelListVisibility: response.data.labelListVisibility,\n color: response.data.color,\n });\n}\n\nexport async function handleDeleteLabel(\n gmail: gmail_v1.Gmail,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(DeleteLabelSchema, args);\n if (!validation.success) return validation.response;\n const { labelId } = validation.data;\n\n // Prevent deletion of system labels\n if (SYSTEM_LABELS.has(labelId)) {\n return errorResponse(`Cannot delete system label: ${labelId}`, { code: \"INVALID_INPUT\" });\n }\n\n await gmail.users.labels.delete({\n userId: \"me\",\n id: labelId,\n });\n\n log(\"Deleted label\", { labelId });\n\n return successResponse(`Label ${labelId} deleted successfully.`);\n}\n\nexport async function handleListLabels(\n gmail: gmail_v1.Gmail,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(ListLabelsSchema, args);\n if (!validation.success) return validation.response;\n const { includeSystemLabels } = validation.data;\n\n const response = await gmail.users.labels.list({\n userId: \"me\",\n });\n\n let labels = response.data.labels || [];\n\n // Separate system and user labels\n const systemLabels = labels.filter((l) => l.type === \"system\");\n const userLabels = labels.filter((l) => l.type === \"user\");\n\n if (!includeSystemLabels) {\n labels = userLabels;\n }\n\n const labelData = labels.map((l) => ({\n id: l.id,\n name: l.name,\n type: l.type,\n messageListVisibility: l.messageListVisibility,\n labelListVisibility: l.labelListVisibility,\n color: l.color,\n messagesTotal: l.messagesTotal,\n messagesUnread: l.messagesUnread,\n }));\n\n log(\"Listed labels\", {\n total: labels.length,\n system: systemLabels.length,\n user: userLabels.length,\n });\n\n return structuredResponse(\n `Found ${labels.length} label(s):\\n\\n${toToon({ labels: labelData })}`,\n {\n labels: labelData,\n systemLabelCount: systemLabels.length,\n userLabelCount: userLabels.length,\n },\n );\n}\n\nexport async function handleGetOrCreateLabel(\n gmail: gmail_v1.Gmail,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(GetOrCreateLabelSchema, args);\n if (!validation.success) return validation.response;\n const { name, messageListVisibility, labelListVisibility, backgroundColor, textColor } =\n validation.data;\n\n // First try to find existing label\n const listResponse = await gmail.users.labels.list({\n userId: \"me\",\n });\n\n const existingLabel = listResponse.data.labels?.find(\n (l) => l.name?.toLowerCase() === name.toLowerCase(),\n );\n\n if (existingLabel) {\n return structuredResponse(`Label \"${name}\" already exists.\\nID: ${existingLabel.id}`, {\n id: existingLabel.id,\n name: existingLabel.name,\n type: existingLabel.type,\n created: false,\n });\n }\n\n // Create new label\n const createResponse = await gmail.users.labels.create({\n userId: \"me\",\n requestBody: {\n name,\n messageListVisibility,\n labelListVisibility,\n color:\n backgroundColor || textColor\n ? {\n backgroundColor,\n textColor,\n }\n : undefined,\n },\n });\n\n log(\"Created label (get_or_create)\", { labelId: createResponse.data.id, name });\n\n return structuredResponse(\n `Label \"${name}\" created successfully.\\nID: ${createResponse.data.id}`,\n {\n id: createResponse.data.id,\n name: createResponse.data.name,\n type: createResponse.data.type,\n created: true,\n },\n );\n}\n\n// ============================================================================\n// Filter Management\n// ============================================================================\n\n// Helper to build filter criteria from template\nfunction buildFilterFromTemplate(data: {\n template: string;\n labelIds: string[];\n archive?: boolean;\n email?: string;\n subject?: string;\n sizeBytes?: number;\n listAddress?: string;\n}): { criteria: gmail_v1.Schema$FilterCriteria; action: gmail_v1.Schema$FilterAction } {\n const action: gmail_v1.Schema$FilterAction = {\n addLabelIds: data.labelIds,\n removeLabelIds: data.archive ? [\"INBOX\"] : undefined,\n };\n\n let criteria: gmail_v1.Schema$FilterCriteria;\n\n switch (data.template) {\n case \"fromSender\":\n criteria = { from: data.email };\n break;\n case \"withSubject\":\n criteria = { subject: data.subject };\n break;\n case \"withAttachments\":\n criteria = { hasAttachment: true };\n break;\n case \"largeEmails\":\n criteria = { size: data.sizeBytes, sizeComparison: \"larger\" };\n break;\n case \"mailingList\":\n criteria = { query: `list:${data.listAddress || data.email}` };\n break;\n default:\n criteria = {};\n }\n\n return { criteria, action };\n}\n\nexport async function handleCreateFilter(\n gmail: gmail_v1.Gmail,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(CreateFilterSchema, args);\n if (!validation.success) return validation.response;\n const data = validation.data;\n\n let filterCriteria: gmail_v1.Schema$FilterCriteria;\n let filterAction: gmail_v1.Schema$FilterAction;\n\n if (data.template) {\n // Template mode\n const built = buildFilterFromTemplate({\n template: data.template,\n labelIds: data.labelIds!,\n archive: data.archive,\n email: data.email,\n subject: data.subject,\n sizeBytes: data.sizeBytes,\n listAddress: data.listAddress,\n });\n filterCriteria = built.criteria;\n filterAction = built.action;\n } else {\n // Direct mode\n const criteria = data.criteria!;\n const action = data.action!;\n filterCriteria = {\n from: criteria.from,\n to: criteria.to,\n subject: criteria.subject,\n query: criteria.query,\n hasAttachment: criteria.hasAttachment,\n excludeChats: criteria.excludeChats,\n size: criteria.size,\n sizeComparison: criteria.sizeComparison,\n };\n filterAction = {\n addLabelIds: action.addLabelIds,\n removeLabelIds: action.removeLabelIds,\n forward: action.forward,\n };\n }\n\n const response = await gmail.users.settings.filters.create({\n userId: \"me\",\n requestBody: {\n criteria: filterCriteria,\n action: filterAction,\n },\n });\n\n log(\"Created filter\", { filterId: response.data.id, template: data.template });\n\n return structuredResponse(\n `Filter created successfully.${data.template ? ` (template: ${data.template})` : \"\"}\\nID: ${response.data.id}`,\n {\n id: response.data.id,\n template: data.template,\n criteria: response.data.criteria,\n action: response.data.action,\n },\n );\n}\n\nexport async function handleListFilters(\n gmail: gmail_v1.Gmail,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(ListFiltersSchema, args);\n if (!validation.success) return validation.response;\n const { filterId } = validation.data;\n\n // If filterId provided, get that specific filter\n if (filterId) {\n const response = await gmail.users.settings.filters.get({\n userId: \"me\",\n id: filterId,\n });\n\n const filter = response.data;\n const criteriaStr = [\n filter.criteria?.from ? `From: ${filter.criteria.from}` : null,\n filter.criteria?.to ? `To: ${filter.criteria.to}` : null,\n filter.criteria?.subject ? `Subject: ${filter.criteria.subject}` : null,\n filter.criteria?.query ? `Query: ${filter.criteria.query}` : null,\n filter.criteria?.hasAttachment ? \"Has attachment\" : null,\n ]\n .filter(Boolean)\n .join(\"\\n\");\n\n const actionStr = [\n filter.action?.addLabelIds ? `Add labels: ${filter.action.addLabelIds.join(\", \")}` : null,\n filter.action?.removeLabelIds\n ? `Remove labels: ${filter.action.removeLabelIds.join(\", \")}`\n : null,\n filter.action?.forward ? `Forward to: ${filter.action.forward}` : null,\n ]\n .filter(Boolean)\n .join(\"\\n\");\n\n log(\"Retrieved filter\", { filterId });\n\n return structuredResponse(\n `Filter: ${filterId}\\n\\nCriteria:\\n${criteriaStr || \"None\"}\\n\\nActions:\\n${actionStr || \"None\"}`,\n {\n id: filter.id,\n criteria: filter.criteria,\n action: filter.action,\n },\n );\n }\n\n // List all filters\n const response = await gmail.users.settings.filters.list({\n userId: \"me\",\n });\n\n const filters = response.data.filter || [];\n\n if (filters.length === 0) {\n return structuredResponse(\"No filters found.\", { filters: [] });\n }\n\n const filterData = filters.map((f) => ({\n id: f.id,\n criteria: f.criteria,\n action: f.action,\n }));\n\n log(\"Listed filters\", { count: filters.length });\n\n return structuredResponse(\n `Found ${filters.length} filter(s):\\n\\n${toToon({ filters: filterData })}`,\n {\n filters: filterData,\n },\n );\n}\n\nexport async function handleDeleteFilter(\n gmail: gmail_v1.Gmail,\n args: unknown,\n): Promise<ToolResponse> {\n const validation = validateArgs(DeleteFilterSchema, args);\n if (!validation.success) return validation.response;\n const { filterId } = validation.data;\n\n await gmail.users.settings.filters.delete({\n userId: \"me\",\n id: filterId,\n });\n\n log(\"Deleted filter\", { filterId });\n\n return successResponse(`Filter ${filterId} deleted successfully.`);\n}\n", "/**\n * Discovery handlers for tool introspection.\n */\n\nimport {\n SERVICE_TOOL_MAP,\n unifiedTools,\n discoveryTools,\n type ToolDefinition,\n} from \"../tools/definitions.js\";\nimport { isServiceEnabled, areUnifiedToolsEnabled, type ServiceName } from \"../config/index.js\";\nimport { successResponse, structuredResponse, type ToolResponse } from \"../utils/responses.js\";\n\ninterface ListToolsInput {\n service?: string;\n keyword?: string;\n includeSchemas?: boolean;\n}\n\ninterface ToolInfo {\n name: string;\n description: string;\n service: string;\n inputSchema?: unknown;\n outputSchema?: unknown;\n}\n\n/**\n * List available tools with optional filtering by service or keyword.\n */\nexport async function handleListTools(args: unknown): Promise<ToolResponse> {\n const input = args as ListToolsInput;\n const { service, keyword, includeSchemas = false } = input;\n\n const results: ToolInfo[] = [];\n const availableServices: string[] = [];\n\n // Helper to add tools from a service\n const addToolsFromService = (serviceName: string, tools: ToolDefinition[]) => {\n for (const tool of tools) {\n // Filter by keyword if provided\n if (keyword) {\n const lowerKeyword = keyword.toLowerCase();\n const matchesName = tool.name.toLowerCase().includes(lowerKeyword);\n const matchesDesc = tool.description.toLowerCase().includes(lowerKeyword);\n if (!matchesName && !matchesDesc) continue;\n }\n\n const toolInfo: ToolInfo = {\n name: tool.name,\n description: tool.description,\n service: serviceName,\n };\n\n if (includeSchemas) {\n toolInfo.inputSchema = tool.inputSchema;\n if (tool.outputSchema) {\n toolInfo.outputSchema = tool.outputSchema;\n }\n }\n\n results.push(toolInfo);\n }\n };\n\n // Add discovery tools (always available)\n if (!service || service === \"discovery\") {\n addToolsFromService(\"discovery\", discoveryTools);\n if (!availableServices.includes(\"discovery\")) {\n availableServices.push(\"discovery\");\n }\n }\n\n // Add tools from each enabled service\n for (const [svcName, serviceTools] of Object.entries(SERVICE_TOOL_MAP)) {\n if (isServiceEnabled(svcName as ServiceName)) {\n if (!availableServices.includes(svcName)) {\n availableServices.push(svcName);\n }\n\n // Filter by service if provided\n if (service && service !== svcName) continue;\n\n addToolsFromService(svcName, serviceTools);\n }\n }\n\n // Add unified tools if enabled\n if (areUnifiedToolsEnabled()) {\n if (!availableServices.includes(\"unified\")) {\n availableServices.push(\"unified\");\n }\n\n if (!service || service === \"unified\") {\n addToolsFromService(\"unified\", unifiedTools);\n }\n }\n\n const data = {\n tools: results,\n totalCount: results.length,\n services: availableServices,\n };\n\n if (results.length === 0) {\n const filterDesc = [\n service ? `service=${service}` : null,\n keyword ? `keyword=\"${keyword}\"` : null,\n ]\n .filter(Boolean)\n .join(\", \");\n return successResponse(`No tools found matching filters: ${filterDesc || \"none\"}`);\n }\n\n const summary = includeSchemas\n ? `Found ${results.length} tool(s) with full schemas`\n : `Found ${results.length} tool(s): ${results.map((t) => t.name).join(\", \")}`;\n\n return structuredResponse(summary, data);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["authClient", "init_services", "resolve", "server", "server", "path", "init_services", "google", "OAuth2Client", "fs", "path", "isExpired", "os", "path", "path", "os", "OAuth2Client", "resolve", "resolve", "join", "dirname", "z", "z", "z", "ColorSchema", "z", "z", "z", "TEXT_MIME_TYPES", "drive", "processBatchWithProgress", "withRateLimitedBatch", "drive", "TEXT_MIME_TYPES", "fs", "path", "drive", "TTL_MS", "drive", "drive", "drive", "randomUUID", "randomUUID", "fs", "path", "response", "dirname", "join", "google", "drive"]
|
|
7
7
|
}
|