@piotr-agier/google-drive-mcp 1.1.2 → 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/README.md +13 -0
- package/dist/index.js +305 -33
- package/dist/index.js.map +2 -2
- package/package.json +2 -2
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/index.ts", "../src/auth/client.ts", "../src/auth/utils.ts", "../src/auth/server.ts", "../src/auth/tokenManager.ts", "../src/auth.ts"],
|
|
4
|
-
"sourcesContent": ["#!/usr/bin/env node\r\n\r\nimport { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\r\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\r\nimport {\r\n CallToolRequestSchema,\r\n ListResourcesRequestSchema,\r\n ListToolsRequestSchema,\r\n ReadResourceRequestSchema,\r\n} from \"@modelcontextprotocol/sdk/types.js\";\r\nimport { google } from \"googleapis\";\r\nimport type { drive_v3 } from \"googleapis\";\r\nimport { v4 as uuidv4 } from 'uuid';\r\nimport { authenticate, runAuthCommand, AuthServer, initializeOAuth2Client } from './auth.js';\r\nimport { z } from 'zod';\r\nimport { fileURLToPath } from 'url';\r\nimport { readFileSync } from 'fs';\r\nimport { join, dirname } from 'path';\r\n\r\n// Drive service - will be created with auth when needed\r\nlet drive: any = null;\r\n\r\n// Helper to ensure drive service has current auth\r\nfunction ensureDriveService() {\r\n if (!authClient) {\r\n throw new Error('Authentication required');\r\n }\r\n \r\n // Log detailed auth client info\r\n log('About to create drive service', {\r\n authClientType: authClient?.constructor?.name,\r\n hasCredentials: !!authClient.credentials,\r\n credentialsKeys: authClient.credentials ? Object.keys(authClient.credentials) : [],\r\n accessTokenLength: authClient.credentials?.access_token?.length,\r\n accessTokenPrefix: authClient.credentials?.access_token?.substring(0, 20),\r\n expiryDate: authClient.credentials?.expiry_date,\r\n isExpired: authClient.credentials?.expiry_date ? Date.now() > authClient.credentials.expiry_date : 'no expiry'\r\n });\r\n \r\n // Create drive service with auth parameter directly\r\n drive = google.drive({ version: 'v3', auth: authClient });\r\n \r\n log('Drive service created/updated', {\r\n hasAuth: !!authClient,\r\n hasCredentials: !!authClient.credentials,\r\n hasAccessToken: !!authClient.credentials?.access_token\r\n });\r\n \r\n // Test the auth by making a simple API call\r\n drive.about.get({ fields: 'user' })\r\n .then((response: any) => {\r\n log('Auth test successful, user:', response.data.user?.emailAddress);\r\n })\r\n .catch((error: any) => {\r\n log('Auth test failed:', error.message || error);\r\n if (error.response) {\r\n log('Auth test error details:', {\r\n status: error.response.status,\r\n statusText: error.response.statusText,\r\n headers: error.response.headers,\r\n data: error.response.data\r\n });\r\n }\r\n });\r\n}\r\n\r\n// -----------------------------------------------------------------------------\r\n// CONSTANTS & CONFIG\r\n// -----------------------------------------------------------------------------\r\nconst FOLDER_MIME_TYPE = 'application/vnd.google-apps.folder';\r\nconst TEXT_MIME_TYPES = {\r\n txt: 'text/plain',\r\n md: 'text/markdown'\r\n};\r\n// Global auth client - will be initialized on first use\r\nlet authClient: any = null;\r\nlet authenticationPromise: Promise<any> | null = null;\r\n\r\n// Get package version\r\nconst __filename = fileURLToPath(import.meta.url);\r\nconst __dirname = dirname(__filename);\r\nconst packageJsonPath = join(__dirname, '..', 'package.json');\r\nconst packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\r\nconst VERSION = packageJson.version;\r\n\r\n// -----------------------------------------------------------------------------\r\n// LOGGING UTILITY\r\n// -----------------------------------------------------------------------------\r\nfunction log(message: string, data?: any) {\r\n const timestamp = new Date().toISOString();\r\n const logMessage = data\r\n ? `[${timestamp}] ${message}: ${JSON.stringify(data)}`\r\n : `[${timestamp}] ${message}`;\r\n console.error(logMessage);\r\n}\r\n\r\n// -----------------------------------------------------------------------------\r\n// HELPER FUNCTIONS\r\n// -----------------------------------------------------------------------------\r\nfunction getExtensionFromFilename(filename: string): string {\r\n return filename.split('.').pop()?.toLowerCase() || '';\r\n}\r\n\r\nfunction getMimeTypeFromFilename(filename: string): string {\r\n const ext = getExtensionFromFilename(filename);\r\n return TEXT_MIME_TYPES[ext as keyof typeof TEXT_MIME_TYPES] || 'text/plain';\r\n}\r\n\r\n\r\n\r\n/**\r\n * Resolve a slash-delimited path (e.g. \"/some/folder\") within Google Drive\r\n * into a folder ID. Creates folders if they don't exist.\r\n */\r\nasync function resolvePath(pathStr: string): Promise<string> {\r\n if (!pathStr || pathStr === '/') return 'root';\r\n\r\n // Note: This function is called after ensureAuthenticated, so drive should exist\r\n const parts = pathStr.replace(/^\\/+|\\/+$/g, '').split('/');\r\n let currentFolderId: string = 'root';\r\n\r\n for (const part of parts) {\r\n if (!part) continue;\r\n let response = await drive.files.list({\r\n q: `'${currentFolderId}' in parents and name = '${part}' and mimeType = '${FOLDER_MIME_TYPE}' and trashed = false`,\r\n fields: 'files(id)',\r\n spaces: 'drive'\r\n });\r\n\r\n // If the folder segment doesn't exist, create it\r\n if (!response.data.files?.length) {\r\n const folderMetadata = {\r\n name: part,\r\n mimeType: FOLDER_MIME_TYPE,\r\n parents: [currentFolderId]\r\n };\r\n const folder = await drive.files.create({\r\n requestBody: folderMetadata,\r\n fields: 'id'\r\n });\r\n\r\n if (!folder.data.id) {\r\n throw new Error(`Failed to create intermediate folder: ${part}`);\r\n }\r\n\r\n currentFolderId = folder.data.id;\r\n } else {\r\n // Folder exists, proceed deeper\r\n currentFolderId = response.data.files[0].id!;\r\n }\r\n }\r\n\r\n return currentFolderId;\r\n}\r\n\r\n\r\n/**\r\n * Resolve a folder ID or path.\r\n * If it's a path (starts with '/'), resolve it.\r\n * If no folder is provided, return 'root'.\r\n */\r\nasync function resolveFolderId(input: string | undefined): Promise<string> {\r\n if (!input) return 'root';\r\n\r\n if (input.startsWith('/')) {\r\n // Input is a path\r\n return resolvePath(input);\r\n } else {\r\n // Input is a folder ID, return as-is\r\n return input;\r\n }\r\n}\r\n\r\n/**\r\n * For text-based files, ensure they have a valid extension.\r\n */\r\nfunction validateTextFileExtension(name: string) {\r\n const ext = getExtensionFromFilename(name);\r\n if (!['txt', 'md'].includes(ext)) {\r\n throw new Error(\"File name must end with .txt or .md for text files.\");\r\n }\r\n}\r\n\r\n/**\r\n * Convert A1 notation to GridRange for Google Sheets API\r\n */\r\nfunction convertA1ToGridRange(a1Notation: string, sheetId: number): any {\r\n // Regular expression to match A1 notation like \"A1\", \"B2:D5\", \"A:A\", \"1:1\"\r\n const rangeRegex = /^([A-Z]*)([0-9]*)(:([A-Z]*)([0-9]*))?$/;\r\n const match = a1Notation.match(rangeRegex);\r\n \r\n if (!match) {\r\n throw new Error(`Invalid A1 notation: ${a1Notation}`);\r\n }\r\n \r\n const [, startCol, startRow, , endCol, endRow] = match;\r\n \r\n const gridRange: any = { sheetId };\r\n \r\n // Convert column letters to numbers (A=0, B=1, etc.)\r\n const colToNum = (col: string): number => {\r\n let num = 0;\r\n for (let i = 0; i < col.length; i++) {\r\n num = num * 26 + (col.charCodeAt(i) - 'A'.charCodeAt(0) + 1);\r\n }\r\n return num - 1;\r\n };\r\n \r\n // Set start indices\r\n if (startCol) gridRange.startColumnIndex = colToNum(startCol);\r\n if (startRow) gridRange.startRowIndex = parseInt(startRow) - 1;\r\n \r\n // Set end indices (exclusive)\r\n if (endCol) {\r\n gridRange.endColumnIndex = colToNum(endCol) + 1;\r\n } else if (startCol && !endCol) {\r\n gridRange.endColumnIndex = gridRange.startColumnIndex + 1;\r\n }\r\n \r\n if (endRow) {\r\n gridRange.endRowIndex = parseInt(endRow);\r\n } else if (startRow && !endRow) {\r\n gridRange.endRowIndex = gridRange.startRowIndex + 1;\r\n }\r\n \r\n return gridRange;\r\n}\r\n\r\n/**\r\n * Check if a file with the given name already exists in the specified folder.\r\n * Returns the file ID if it exists, null otherwise.\r\n */\r\nasync function checkFileExists(name: string, parentFolderId: string = 'root'): Promise<string | null> {\r\n try {\r\n const escapedName = name.replace(/\\\\/g, \"\\\\\\\\\").replace(/'/g, \"\\\\'\");\r\n const query = `name = '${escapedName}' and '${parentFolderId}' in parents and trashed = false`;\r\n \r\n const res = await drive.files.list({\r\n q: query,\r\n fields: 'files(id, name, mimeType)',\r\n pageSize: 1\r\n });\r\n \r\n if (res.data.files && res.data.files.length > 0) {\r\n return res.data.files[0].id || null;\r\n }\r\n return null;\r\n } catch (error) {\r\n log('Error checking file existence:', error);\r\n return null;\r\n }\r\n}\r\n\r\n// -----------------------------------------------------------------------------\r\n// INPUT VALIDATION SCHEMAS\r\n// -----------------------------------------------------------------------------\r\nconst SearchSchema = z.object({\r\n query: z.string().min(1, \"Search query is required\"),\r\n pageSize: z.number().int().min(1).max(100).optional(),\r\n pageToken: z.string().optional()\r\n});\r\n\r\nconst CreateTextFileSchema = z.object({\r\n name: z.string().min(1, \"File name is required\"),\r\n content: z.string(),\r\n parentFolderId: z.string().optional()\r\n});\r\n\r\nconst UpdateTextFileSchema = z.object({\r\n fileId: z.string().min(1, \"File ID is required\"),\r\n content: z.string(),\r\n name: z.string().optional()\r\n});\r\n\r\nconst CreateFolderSchema = z.object({\r\n name: z.string().min(1, \"Folder name is required\"),\r\n parent: z.string().optional()\r\n});\r\n\r\nconst ListFolderSchema = z.object({\r\n folderId: z.string().optional(),\r\n pageSize: z.number().int().min(1).max(100).optional(),\r\n pageToken: z.string().optional()\r\n});\r\n\r\nconst DeleteItemSchema = z.object({\r\n itemId: z.string().min(1, \"Item ID is required\")\r\n});\r\n\r\nconst RenameItemSchema = z.object({\r\n itemId: z.string().min(1, \"Item ID is required\"),\r\n newName: z.string().min(1, \"New name is required\")\r\n});\r\n\r\nconst MoveItemSchema = z.object({\r\n itemId: z.string().min(1, \"Item ID is required\"),\r\n destinationFolderId: z.string().optional()\r\n});\r\n\r\nconst CreateGoogleDocSchema = z.object({\r\n name: z.string().min(1, \"Document name is required\"),\r\n content: z.string(),\r\n parentFolderId: z.string().optional()\r\n});\r\n\r\nconst UpdateGoogleDocSchema = z.object({\r\n documentId: z.string().min(1, \"Document ID is required\"),\r\n content: z.string()\r\n});\r\n\r\nconst CreateGoogleSheetSchema = z.object({\r\n name: z.string().min(1, \"Sheet name is required\"),\r\n data: z.array(z.array(z.string())),\r\n parentFolderId: z.string().optional()\r\n});\r\n\r\nconst UpdateGoogleSheetSchema = z.object({\r\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\r\n range: z.string().min(1, \"Range is required\"),\r\n data: z.array(z.array(z.string()))\r\n});\r\n\r\nconst GetGoogleSheetContentSchema = z.object({\r\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\r\n range: z.string().min(1, \"Range is required\")\r\n});\r\n\r\nconst FormatGoogleSheetCellsSchema = z.object({\r\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\r\n range: z.string().min(1, \"Range is required\"),\r\n backgroundColor: z.object({\r\n red: z.number().min(0).max(1).optional(),\r\n green: z.number().min(0).max(1).optional(),\r\n blue: z.number().min(0).max(1).optional()\r\n }).optional(),\r\n horizontalAlignment: z.enum([\"LEFT\", \"CENTER\", \"RIGHT\"]).optional(),\r\n verticalAlignment: z.enum([\"TOP\", \"MIDDLE\", \"BOTTOM\"]).optional(),\r\n wrapStrategy: z.enum([\"OVERFLOW_CELL\", \"CLIP\", \"WRAP\"]).optional()\r\n});\r\n\r\nconst FormatGoogleSheetTextSchema = z.object({\r\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\r\n range: z.string().min(1, \"Range is required\"),\r\n bold: z.boolean().optional(),\r\n italic: z.boolean().optional(),\r\n strikethrough: z.boolean().optional(),\r\n underline: z.boolean().optional(),\r\n fontSize: z.number().min(1).optional(),\r\n fontFamily: z.string().optional(),\r\n foregroundColor: z.object({\r\n red: z.number().min(0).max(1).optional(),\r\n green: z.number().min(0).max(1).optional(),\r\n blue: z.number().min(0).max(1).optional()\r\n }).optional()\r\n});\r\n\r\nconst FormatGoogleSheetNumbersSchema = z.object({\r\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\r\n range: z.string().min(1, \"Range is required\"),\r\n pattern: z.string().min(1, \"Pattern is required\"),\r\n type: z.enum([\"NUMBER\", \"CURRENCY\", \"PERCENT\", \"DATE\", \"TIME\", \"DATE_TIME\", \"SCIENTIFIC\"]).optional()\r\n});\r\n\r\nconst SetGoogleSheetBordersSchema = z.object({\r\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\r\n range: z.string().min(1, \"Range is required\"),\r\n style: z.enum([\"SOLID\", \"DASHED\", \"DOTTED\", \"DOUBLE\"]),\r\n width: z.number().min(1).max(3).optional(),\r\n color: z.object({\r\n red: z.number().min(0).max(1).optional(),\r\n green: z.number().min(0).max(1).optional(),\r\n blue: z.number().min(0).max(1).optional()\r\n }).optional(),\r\n top: z.boolean().optional(),\r\n bottom: z.boolean().optional(),\r\n left: z.boolean().optional(),\r\n right: z.boolean().optional(),\r\n innerHorizontal: z.boolean().optional(),\r\n innerVertical: z.boolean().optional()\r\n});\r\n\r\nconst MergeGoogleSheetCellsSchema = z.object({\r\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\r\n range: z.string().min(1, \"Range is required\"),\r\n mergeType: z.enum([\"MERGE_ALL\", \"MERGE_COLUMNS\", \"MERGE_ROWS\"])\r\n});\r\n\r\nconst AddGoogleSheetConditionalFormatSchema = z.object({\r\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\r\n range: z.string().min(1, \"Range is required\"),\r\n condition: z.object({\r\n type: z.enum([\"NUMBER_GREATER\", \"NUMBER_LESS\", \"TEXT_CONTAINS\", \"TEXT_STARTS_WITH\", \"TEXT_ENDS_WITH\", \"CUSTOM_FORMULA\"]),\r\n value: z.string()\r\n }),\r\n format: z.object({\r\n backgroundColor: z.object({\r\n red: z.number().min(0).max(1).optional(),\r\n green: z.number().min(0).max(1).optional(),\r\n blue: z.number().min(0).max(1).optional()\r\n }).optional(),\r\n textFormat: z.object({\r\n bold: z.boolean().optional(),\r\n foregroundColor: z.object({\r\n red: z.number().min(0).max(1).optional(),\r\n green: z.number().min(0).max(1).optional(),\r\n blue: z.number().min(0).max(1).optional()\r\n }).optional()\r\n }).optional()\r\n })\r\n});\r\n\r\nconst CreateGoogleSlidesSchema = z.object({\r\n name: z.string().min(1, \"Presentation name is required\"),\r\n slides: z.array(z.object({\r\n title: z.string(),\r\n content: z.string()\r\n })).min(1, \"At least one slide is required\"),\r\n parentFolderId: z.string().optional()\r\n});\r\n\r\nconst UpdateGoogleSlidesSchema = z.object({\r\n presentationId: z.string().min(1, \"Presentation ID is required\"),\r\n slides: z.array(z.object({\r\n title: z.string(),\r\n content: z.string()\r\n })).min(1, \"At least one slide is required\")\r\n});\r\n\r\nconst FormatGoogleDocTextSchema = z.object({\r\n documentId: z.string().min(1, \"Document ID is required\"),\r\n startIndex: z.number().min(1, \"Start index must be at least 1\"),\r\n endIndex: z.number().min(1, \"End index must be at least 1\"),\r\n bold: z.boolean().optional(),\r\n italic: z.boolean().optional(),\r\n underline: z.boolean().optional(),\r\n strikethrough: z.boolean().optional(),\r\n fontSize: z.number().optional(),\r\n foregroundColor: z.object({\r\n red: z.number().min(0).max(1).optional(),\r\n green: z.number().min(0).max(1).optional(),\r\n blue: z.number().min(0).max(1).optional()\r\n }).optional()\r\n});\r\n\r\nconst FormatGoogleDocParagraphSchema = z.object({\r\n documentId: z.string().min(1, \"Document ID is required\"),\r\n startIndex: z.number().min(1, \"Start index must be at least 1\"),\r\n endIndex: z.number().min(1, \"End index must be at least 1\"),\r\n namedStyleType: z.enum(['NORMAL_TEXT', 'TITLE', 'SUBTITLE', 'HEADING_1', 'HEADING_2', 'HEADING_3', 'HEADING_4', 'HEADING_5', 'HEADING_6']).optional(),\r\n alignment: z.enum(['START', 'CENTER', 'END', 'JUSTIFIED']).optional(),\r\n lineSpacing: z.number().optional(),\r\n spaceAbove: z.number().optional(),\r\n spaceBelow: z.number().optional()\r\n});\r\n\r\nconst GetGoogleDocContentSchema = z.object({\r\n documentId: z.string().min(1, \"Document ID is required\")\r\n});\r\n\r\n// Google Slides Formatting Schemas\r\nconst GetGoogleSlidesContentSchema = z.object({\r\n presentationId: z.string().min(1, \"Presentation ID is required\"),\r\n slideIndex: z.number().min(0).optional()\r\n});\r\n\r\nconst FormatGoogleSlidesTextSchema = z.object({\r\n presentationId: z.string().min(1, \"Presentation ID is required\"),\r\n objectId: z.string().min(1, \"Object ID is required\"),\r\n startIndex: z.number().min(0).optional(),\r\n endIndex: z.number().min(0).optional(),\r\n bold: z.boolean().optional(),\r\n italic: z.boolean().optional(),\r\n underline: z.boolean().optional(),\r\n strikethrough: z.boolean().optional(),\r\n fontSize: z.number().optional(),\r\n fontFamily: z.string().optional(),\r\n foregroundColor: z.object({\r\n red: z.number().min(0).max(1).optional(),\r\n green: z.number().min(0).max(1).optional(),\r\n blue: z.number().min(0).max(1).optional()\r\n }).optional()\r\n});\r\n\r\nconst FormatGoogleSlidesParagraphSchema = z.object({\r\n presentationId: z.string().min(1, \"Presentation ID is required\"),\r\n objectId: z.string().min(1, \"Object ID is required\"),\r\n alignment: z.enum(['START', 'CENTER', 'END', 'JUSTIFIED']).optional(),\r\n lineSpacing: z.number().optional(),\r\n bulletStyle: z.enum(['NONE', 'DISC', 'ARROW', 'SQUARE', 'DIAMOND', 'STAR', 'NUMBERED']).optional()\r\n});\r\n\r\nconst StyleGoogleSlidesShapeSchema = z.object({\r\n presentationId: z.string().min(1, \"Presentation ID is required\"),\r\n objectId: z.string().min(1, \"Shape object ID is required\"),\r\n backgroundColor: z.object({\r\n red: z.number().min(0).max(1).optional(),\r\n green: z.number().min(0).max(1).optional(),\r\n blue: z.number().min(0).max(1).optional(),\r\n alpha: z.number().min(0).max(1).optional()\r\n }).optional(),\r\n outlineColor: z.object({\r\n red: z.number().min(0).max(1).optional(),\r\n green: z.number().min(0).max(1).optional(),\r\n blue: z.number().min(0).max(1).optional()\r\n }).optional(),\r\n outlineWeight: z.number().optional(),\r\n outlineDashStyle: z.enum(['SOLID', 'DOT', 'DASH', 'DASH_DOT', 'LONG_DASH', 'LONG_DASH_DOT']).optional()\r\n});\r\n\r\nconst SetGoogleSlidesBackgroundSchema = z.object({\r\n presentationId: z.string().min(1, \"Presentation ID is required\"),\r\n pageObjectIds: z.array(z.string()).min(1, \"At least one page object ID is required\"),\r\n backgroundColor: z.object({\r\n red: z.number().min(0).max(1).optional(),\r\n green: z.number().min(0).max(1).optional(),\r\n blue: z.number().min(0).max(1).optional(),\r\n alpha: z.number().min(0).max(1).optional()\r\n })\r\n});\r\n\r\nconst CreateGoogleSlidesTextBoxSchema = z.object({\r\n presentationId: z.string().min(1, \"Presentation ID is required\"),\r\n pageObjectId: z.string().min(1, \"Page object ID is required\"),\r\n text: z.string().min(1, \"Text content is required\"),\r\n x: z.number(),\r\n y: z.number(),\r\n width: z.number(),\r\n height: z.number(),\r\n fontSize: z.number().optional(),\r\n bold: z.boolean().optional(),\r\n italic: z.boolean().optional()\r\n});\r\n\r\nconst CreateGoogleSlidesShapeSchema = z.object({\r\n presentationId: z.string().min(1, \"Presentation ID is required\"),\r\n pageObjectId: z.string().min(1, \"Page object ID is required\"),\r\n shapeType: z.enum(['RECTANGLE', 'ELLIPSE', 'DIAMOND', 'TRIANGLE', 'STAR', 'ROUND_RECTANGLE', 'ARROW']),\r\n x: z.number(),\r\n y: z.number(),\r\n width: z.number(),\r\n height: z.number(),\r\n backgroundColor: z.object({\r\n red: z.number().min(0).max(1).optional(),\r\n green: z.number().min(0).max(1).optional(),\r\n blue: z.number().min(0).max(1).optional(),\r\n alpha: z.number().min(0).max(1).optional()\r\n }).optional()\r\n});\r\n\r\n// -----------------------------------------------------------------------------\r\n// SERVER SETUP\r\n// -----------------------------------------------------------------------------\r\nconst server = new Server(\r\n {\r\n name: \"google-drive-mcp\",\r\n version: VERSION,\r\n },\r\n {\r\n capabilities: {\r\n resources: {},\r\n tools: {},\r\n },\r\n },\r\n);\r\n\r\n// -----------------------------------------------------------------------------\r\n// AUTHENTICATION HELPER\r\n// -----------------------------------------------------------------------------\r\nasync function ensureAuthenticated() {\r\n if (!authClient) {\r\n // If authentication is already in progress, wait for it\r\n if (authenticationPromise) {\r\n log('Authentication already in progress, waiting...');\r\n authClient = await authenticationPromise;\r\n return;\r\n }\r\n \r\n log('Initializing authentication');\r\n // Store the promise to prevent concurrent authentication attempts\r\n authenticationPromise = authenticate();\r\n \r\n try {\r\n authClient = await authenticationPromise;\r\n log('Authentication complete', {\r\n authClientType: authClient?.constructor?.name,\r\n hasCredentials: !!authClient?.credentials,\r\n hasAccessToken: !!authClient?.credentials?.access_token\r\n });\r\n // Ensure drive service is created with auth\r\n ensureDriveService();\r\n } finally {\r\n // Clear the promise after completion (success or failure)\r\n authenticationPromise = null;\r\n }\r\n }\r\n \r\n // If we already have authClient, ensure drive is up to date\r\n ensureDriveService();\r\n}\r\n\r\n// -----------------------------------------------------------------------------\r\n// MCP REQUEST HANDLERS\r\n// -----------------------------------------------------------------------------\r\n\r\nserver.setRequestHandler(ListResourcesRequestSchema, async (request) => {\r\n await ensureAuthenticated();\r\n log('Handling ListResources request', { params: request.params });\r\n const pageSize = 10;\r\n const params: {\r\n pageSize: number,\r\n fields: string,\r\n pageToken?: string,\r\n q: string\r\n } = {\r\n pageSize,\r\n fields: \"nextPageToken, files(id, name, mimeType)\",\r\n q: `trashed = false`\r\n };\r\n\r\n if (request.params?.cursor) {\r\n params.pageToken = request.params.cursor;\r\n }\r\n\r\n const res = await drive.files.list(params);\r\n log('Listed files', { count: res.data.files?.length });\r\n const files = res.data.files || [];\r\n\r\n return {\r\n resources: files.map((file: drive_v3.Schema$File) => ({\r\n uri: `gdrive:///${file.id}`,\r\n mimeType: file.mimeType || 'application/octet-stream',\r\n name: file.name || 'Untitled',\r\n })),\r\n nextCursor: res.data.nextPageToken,\r\n };\r\n});\r\n\r\nserver.setRequestHandler(ReadResourceRequestSchema, async (request) => {\r\n await ensureAuthenticated();\r\n log('Handling ReadResource request', { uri: request.params.uri });\r\n const fileId = request.params.uri.replace(\"gdrive:///\", \"\");\r\n\r\n const file = await drive.files.get({\r\n fileId,\r\n fields: \"mimeType\",\r\n });\r\n const mimeType = file.data.mimeType;\r\n\r\n if (!mimeType) {\r\n throw new Error(\"File has no MIME type.\");\r\n }\r\n\r\n if (mimeType.startsWith(\"application/vnd.google-apps\")) {\r\n // Export logic for Google Docs/Sheets/Slides\r\n let exportMimeType;\r\n switch (mimeType) {\r\n case \"application/vnd.google-apps.document\": exportMimeType = \"text/markdown\"; break;\r\n case \"application/vnd.google-apps.spreadsheet\": exportMimeType = \"text/csv\"; break;\r\n case \"application/vnd.google-apps.presentation\": exportMimeType = \"text/plain\"; break;\r\n case \"application/vnd.google-apps.drawing\": exportMimeType = \"image/png\"; break;\r\n default: exportMimeType = \"text/plain\"; break;\r\n }\r\n\r\n const res = await drive.files.export(\r\n { fileId, mimeType: exportMimeType },\r\n { responseType: \"text\" },\r\n );\r\n\r\n log('Successfully read resource', { fileId, mimeType });\r\n return {\r\n contents: [\r\n {\r\n uri: request.params.uri,\r\n mimeType: exportMimeType,\r\n text: res.data,\r\n },\r\n ],\r\n };\r\n } else {\r\n // Regular file download\r\n const res = await drive.files.get(\r\n { fileId, alt: \"media\" },\r\n { responseType: \"arraybuffer\" },\r\n );\r\n const contentMime = mimeType || \"application/octet-stream\";\r\n\r\n if (contentMime.startsWith(\"text/\") || contentMime === \"application/json\") {\r\n return {\r\n contents: [\r\n {\r\n uri: request.params.uri,\r\n mimeType: contentMime,\r\n text: Buffer.from(res.data as ArrayBuffer).toString(\"utf-8\"),\r\n },\r\n ],\r\n };\r\n } else {\r\n return {\r\n contents: [\r\n {\r\n uri: request.params.uri,\r\n mimeType: contentMime,\r\n blob: Buffer.from(res.data as ArrayBuffer).toString(\"base64\"),\r\n },\r\n ],\r\n };\r\n }\r\n }\r\n});\r\n\r\nserver.setRequestHandler(ListToolsRequestSchema, async () => {\r\n return {\r\n tools: [\r\n {\r\n name: \"search\",\r\n description: \"Search for files in Google Drive\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n query: { type: \"string\", description: \"Search query\" },\r\n pageSize: { type: \"number\", description: \"Results per page (default 50, max 100)\" },\r\n pageToken: { type: \"string\", description: \"Token for next page of results\" }\r\n },\r\n required: [\"query\"],\r\n },\r\n },\r\n {\r\n name: \"createTextFile\",\r\n description: \"Create a new text or markdown file\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n name: { type: \"string\", description: \"File name (.txt or .md)\" },\r\n content: { type: \"string\", description: \"File content\" },\r\n parentFolderId: { type: \"string\", description: \"Optional parent folder ID\", optional: true }\r\n },\r\n required: [\"name\", \"content\"]\r\n }\r\n },\r\n {\r\n name: \"updateTextFile\",\r\n description: \"Update an existing text or markdown file\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n fileId: { type: \"string\", description: \"ID of the file to update\" },\r\n content: { type: \"string\", description: \"New file content\" },\r\n name: { type: \"string\", description: \"Optional new name (.txt or .md)\", optional: true }\r\n },\r\n required: [\"fileId\", \"content\"]\r\n }\r\n },\r\n {\r\n name: \"createFolder\",\r\n description: \"Create a new folder in Google Drive\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n name: { type: \"string\", description: \"Folder name\" },\r\n parent: { type: \"string\", description: \"Optional parent folder ID or path\", optional: true }\r\n },\r\n required: [\"name\"]\r\n }\r\n },\r\n {\r\n name: \"listFolder\",\r\n description: \"List contents of a folder (defaults to root)\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n folderId: { type: \"string\", description: \"Folder ID\", optional: true },\r\n pageSize: { type: \"number\", description: \"Items to return (default 50, max 100)\", optional: true },\r\n pageToken: { type: \"string\", description: \"Token for next page\", optional: true }\r\n }\r\n }\r\n },\r\n {\r\n name: \"deleteItem\",\r\n description: \"Move a file or folder to trash (can be restored from Google Drive trash)\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n itemId: { type: \"string\", description: \"ID of the item to delete\" }\r\n },\r\n required: [\"itemId\"]\r\n }\r\n },\r\n {\r\n name: \"renameItem\",\r\n description: \"Rename a file or folder\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n itemId: { type: \"string\", description: \"ID of the item to rename\" },\r\n newName: { type: \"string\", description: \"New name\" }\r\n },\r\n required: [\"itemId\", \"newName\"]\r\n }\r\n },\r\n {\r\n name: \"moveItem\",\r\n description: \"Move a file or folder\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n itemId: { type: \"string\", description: \"ID of the item to move\" },\r\n destinationFolderId: { type: \"string\", description: \"Destination folder ID\", optional: true }\r\n },\r\n required: [\"itemId\"]\r\n }\r\n },\r\n {\r\n name: \"createGoogleDoc\",\r\n description: \"Create a new Google Doc\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n name: { type: \"string\", description: \"Doc name\" },\r\n content: { type: \"string\", description: \"Doc content\" },\r\n parentFolderId: { type: \"string\", description: \"Parent folder ID\", optional: true }\r\n },\r\n required: [\"name\", \"content\"]\r\n }\r\n },\r\n {\r\n name: \"updateGoogleDoc\",\r\n description: \"Update an existing Google Doc\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n documentId: { type: \"string\", description: \"Doc ID\" },\r\n content: { type: \"string\", description: \"New content\" }\r\n },\r\n required: [\"documentId\", \"content\"]\r\n }\r\n },\r\n {\r\n name: \"createGoogleSheet\",\r\n description: \"Create a new Google Sheet\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n name: { type: \"string\", description: \"Sheet name\" },\r\n data: {\r\n type: \"array\",\r\n description: \"Data as array of arrays\",\r\n items: { type: \"array\", items: { type: \"string\" } }\r\n },\r\n parentFolderId: { type: \"string\", description: \"Parent folder ID (defaults to root)\", optional: true }\r\n },\r\n required: [\"name\", \"data\"]\r\n }\r\n },\r\n {\r\n name: \"updateGoogleSheet\",\r\n description: \"Update an existing Google Sheet\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n spreadsheetId: { type: \"string\", description: \"Sheet ID\" },\r\n range: { type: \"string\", description: \"Range to update\" },\r\n data: {\r\n type: \"array\",\r\n items: { type: \"array\", items: { type: \"string\" } }\r\n }\r\n },\r\n required: [\"spreadsheetId\", \"range\", \"data\"]\r\n }\r\n },\r\n {\r\n name: \"getGoogleSheetContent\",\r\n description: \"Get content of a Google Sheet with cell information\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\r\n range: { type: \"string\", description: \"Range to get (e.g., 'Sheet1!A1:C10')\" }\r\n },\r\n required: [\"spreadsheetId\", \"range\"]\r\n }\r\n },\r\n {\r\n name: \"formatGoogleSheetCells\",\r\n description: \"Format cells in a Google Sheet (background, borders, alignment)\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\r\n range: { type: \"string\", description: \"Range to format (e.g., 'A1:C10')\" },\r\n backgroundColor: {\r\n type: \"object\",\r\n description: \"Background color (RGB values 0-1)\",\r\n properties: {\r\n red: { type: \"number\", optional: true },\r\n green: { type: \"number\", optional: true },\r\n blue: { type: \"number\", optional: true }\r\n },\r\n optional: true\r\n },\r\n horizontalAlignment: {\r\n type: \"string\",\r\n description: \"Horizontal alignment\",\r\n enum: [\"LEFT\", \"CENTER\", \"RIGHT\"],\r\n optional: true\r\n },\r\n verticalAlignment: {\r\n type: \"string\",\r\n description: \"Vertical alignment\",\r\n enum: [\"TOP\", \"MIDDLE\", \"BOTTOM\"],\r\n optional: true\r\n },\r\n wrapStrategy: {\r\n type: \"string\",\r\n description: \"Text wrapping\",\r\n enum: [\"OVERFLOW_CELL\", \"CLIP\", \"WRAP\"],\r\n optional: true\r\n }\r\n },\r\n required: [\"spreadsheetId\", \"range\"]\r\n }\r\n },\r\n {\r\n name: \"formatGoogleSheetText\",\r\n description: \"Apply text formatting to cells in a Google Sheet\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\r\n range: { type: \"string\", description: \"Range to format (e.g., 'A1:C10')\" },\r\n bold: { type: \"boolean\", description: \"Make text bold\", optional: true },\r\n italic: { type: \"boolean\", description: \"Make text italic\", optional: true },\r\n strikethrough: { type: \"boolean\", description: \"Strikethrough text\", optional: true },\r\n underline: { type: \"boolean\", description: \"Underline text\", optional: true },\r\n fontSize: { type: \"number\", description: \"Font size in points\", optional: true },\r\n fontFamily: { type: \"string\", description: \"Font family name\", optional: true },\r\n foregroundColor: {\r\n type: \"object\",\r\n description: \"Text color (RGB values 0-1)\",\r\n properties: {\r\n red: { type: \"number\", optional: true },\r\n green: { type: \"number\", optional: true },\r\n blue: { type: \"number\", optional: true }\r\n },\r\n optional: true\r\n }\r\n },\r\n required: [\"spreadsheetId\", \"range\"]\r\n }\r\n },\r\n {\r\n name: \"formatGoogleSheetNumbers\",\r\n description: \"Apply number formatting to cells in a Google Sheet\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\r\n range: { type: \"string\", description: \"Range to format (e.g., 'A1:C10')\" },\r\n pattern: {\r\n type: \"string\",\r\n description: \"Number format pattern (e.g., '#,##0.00', 'yyyy-mm-dd', '$#,##0.00', '0.00%')\"\r\n },\r\n type: {\r\n type: \"string\",\r\n description: \"Format type\",\r\n enum: [\"NUMBER\", \"CURRENCY\", \"PERCENT\", \"DATE\", \"TIME\", \"DATE_TIME\", \"SCIENTIFIC\"],\r\n optional: true\r\n }\r\n },\r\n required: [\"spreadsheetId\", \"range\", \"pattern\"]\r\n }\r\n },\r\n {\r\n name: \"setGoogleSheetBorders\",\r\n description: \"Set borders for cells in a Google Sheet\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\r\n range: { type: \"string\", description: \"Range to format (e.g., 'A1:C10')\" },\r\n style: {\r\n type: \"string\",\r\n description: \"Border style\",\r\n enum: [\"SOLID\", \"DASHED\", \"DOTTED\", \"DOUBLE\"]\r\n },\r\n width: { type: \"number\", description: \"Border width (1-3)\", optional: true },\r\n color: {\r\n type: \"object\",\r\n description: \"Border color (RGB values 0-1)\",\r\n properties: {\r\n red: { type: \"number\", optional: true },\r\n green: { type: \"number\", optional: true },\r\n blue: { type: \"number\", optional: true }\r\n },\r\n optional: true\r\n },\r\n top: { type: \"boolean\", description: \"Apply to top border\", optional: true },\r\n bottom: { type: \"boolean\", description: \"Apply to bottom border\", optional: true },\r\n left: { type: \"boolean\", description: \"Apply to left border\", optional: true },\r\n right: { type: \"boolean\", description: \"Apply to right border\", optional: true },\r\n innerHorizontal: { type: \"boolean\", description: \"Apply to inner horizontal borders\", optional: true },\r\n innerVertical: { type: \"boolean\", description: \"Apply to inner vertical borders\", optional: true }\r\n },\r\n required: [\"spreadsheetId\", \"range\", \"style\"]\r\n }\r\n },\r\n {\r\n name: \"mergeGoogleSheetCells\",\r\n description: \"Merge cells in a Google Sheet\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\r\n range: { type: \"string\", description: \"Range to merge (e.g., 'A1:C3')\" },\r\n mergeType: {\r\n type: \"string\",\r\n description: \"Merge type\",\r\n enum: [\"MERGE_ALL\", \"MERGE_COLUMNS\", \"MERGE_ROWS\"]\r\n }\r\n },\r\n required: [\"spreadsheetId\", \"range\", \"mergeType\"]\r\n }\r\n },\r\n {\r\n name: \"addGoogleSheetConditionalFormat\",\r\n description: \"Add conditional formatting to a Google Sheet\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\r\n range: { type: \"string\", description: \"Range to apply formatting (e.g., 'A1:C10')\" },\r\n condition: {\r\n type: \"object\",\r\n description: \"Condition configuration\",\r\n properties: {\r\n type: {\r\n type: \"string\",\r\n description: \"Condition type\",\r\n enum: [\"NUMBER_GREATER\", \"NUMBER_LESS\", \"TEXT_CONTAINS\", \"TEXT_STARTS_WITH\", \"TEXT_ENDS_WITH\", \"CUSTOM_FORMULA\"]\r\n },\r\n value: { type: \"string\", description: \"Value to compare or formula\" }\r\n }\r\n },\r\n format: {\r\n type: \"object\",\r\n description: \"Format to apply when condition is true\",\r\n properties: {\r\n backgroundColor: {\r\n type: \"object\",\r\n properties: {\r\n red: { type: \"number\", optional: true },\r\n green: { type: \"number\", optional: true },\r\n blue: { type: \"number\", optional: true }\r\n },\r\n optional: true\r\n },\r\n textFormat: {\r\n type: \"object\",\r\n properties: {\r\n bold: { type: \"boolean\", optional: true },\r\n foregroundColor: {\r\n type: \"object\",\r\n properties: {\r\n red: { type: \"number\", optional: true },\r\n green: { type: \"number\", optional: true },\r\n blue: { type: \"number\", optional: true }\r\n },\r\n optional: true\r\n }\r\n },\r\n optional: true\r\n }\r\n }\r\n }\r\n },\r\n required: [\"spreadsheetId\", \"range\", \"condition\", \"format\"]\r\n }\r\n },\r\n {\r\n name: \"createGoogleSlides\",\r\n description: \"Create a new Google Slides presentation\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n name: { type: \"string\", description: \"Presentation name\" },\r\n slides: {\r\n type: \"array\",\r\n description: \"Array of slide objects\",\r\n items: {\r\n type: \"object\",\r\n properties: {\r\n title: { type: \"string\" },\r\n content: { type: \"string\" }\r\n }\r\n }\r\n },\r\n parentFolderId: { type: \"string\", description: \"Parent folder ID (defaults to root)\", optional: true }\r\n },\r\n required: [\"name\", \"slides\"]\r\n }\r\n },\r\n {\r\n name: \"updateGoogleSlides\",\r\n description: \"Update an existing Google Slides presentation\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n presentationId: { type: \"string\", description: \"Presentation ID\" },\r\n slides: {\r\n type: \"array\",\r\n description: \"Array of slide objects to replace existing slides\",\r\n items: {\r\n type: \"object\",\r\n properties: {\r\n title: { type: \"string\" },\r\n content: { type: \"string\" }\r\n }\r\n }\r\n }\r\n },\r\n required: [\"presentationId\", \"slides\"]\r\n }\r\n },\r\n {\r\n name: \"formatGoogleDocText\",\r\n description: \"Apply text formatting to a range in a Google Doc\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n documentId: { type: \"string\", description: \"Document ID\" },\r\n startIndex: { type: \"number\", description: \"Start index (1-based)\" },\r\n endIndex: { type: \"number\", description: \"End index (1-based)\" },\r\n bold: { type: \"boolean\", description: \"Make text bold\", optional: true },\r\n italic: { type: \"boolean\", description: \"Make text italic\", optional: true },\r\n underline: { type: \"boolean\", description: \"Underline text\", optional: true },\r\n strikethrough: { type: \"boolean\", description: \"Strikethrough text\", optional: true },\r\n fontSize: { type: \"number\", description: \"Font size in points\", optional: true },\r\n foregroundColor: {\r\n type: \"object\",\r\n description: \"Text color (RGB values 0-1)\",\r\n properties: {\r\n red: { type: \"number\", optional: true },\r\n green: { type: \"number\", optional: true },\r\n blue: { type: \"number\", optional: true }\r\n },\r\n optional: true\r\n }\r\n },\r\n required: [\"documentId\", \"startIndex\", \"endIndex\"]\r\n }\r\n },\r\n {\r\n name: \"formatGoogleDocParagraph\",\r\n description: \"Apply paragraph formatting to a range in a Google Doc\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n documentId: { type: \"string\", description: \"Document ID\" },\r\n startIndex: { type: \"number\", description: \"Start index (1-based)\" },\r\n endIndex: { type: \"number\", description: \"End index (1-based)\" },\r\n namedStyleType: {\r\n type: \"string\",\r\n description: \"Paragraph style\",\r\n enum: [\"NORMAL_TEXT\", \"TITLE\", \"SUBTITLE\", \"HEADING_1\", \"HEADING_2\", \"HEADING_3\", \"HEADING_4\", \"HEADING_5\", \"HEADING_6\"],\r\n optional: true\r\n },\r\n alignment: {\r\n type: \"string\",\r\n description: \"Text alignment\",\r\n enum: [\"START\", \"CENTER\", \"END\", \"JUSTIFIED\"],\r\n optional: true\r\n },\r\n lineSpacing: { type: \"number\", description: \"Line spacing multiplier\", optional: true },\r\n spaceAbove: { type: \"number\", description: \"Space above paragraph in points\", optional: true },\r\n spaceBelow: { type: \"number\", description: \"Space below paragraph in points\", optional: true }\r\n },\r\n required: [\"documentId\", \"startIndex\", \"endIndex\"]\r\n }\r\n },\r\n {\r\n name: \"getGoogleDocContent\",\r\n description: \"Get content of a Google Doc with text indices for formatting\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n documentId: { type: \"string\", description: \"Document ID\" }\r\n },\r\n required: [\"documentId\"]\r\n }\r\n },\r\n {\r\n name: \"getGoogleSlidesContent\",\r\n description: \"Get content of Google Slides with element IDs for formatting\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n presentationId: { type: \"string\", description: \"Presentation ID\" },\r\n slideIndex: { type: \"number\", description: \"Specific slide index (optional)\", optional: true }\r\n },\r\n required: [\"presentationId\"]\r\n }\r\n },\r\n {\r\n name: \"formatGoogleSlidesText\",\r\n description: \"Apply text formatting to elements in Google Slides\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n presentationId: { type: \"string\", description: \"Presentation ID\" },\r\n objectId: { type: \"string\", description: \"Object ID of the text element\" },\r\n startIndex: { type: \"number\", description: \"Start index (0-based)\", optional: true },\r\n endIndex: { type: \"number\", description: \"End index (0-based)\", optional: true },\r\n bold: { type: \"boolean\", description: \"Make text bold\", optional: true },\r\n italic: { type: \"boolean\", description: \"Make text italic\", optional: true },\r\n underline: { type: \"boolean\", description: \"Underline text\", optional: true },\r\n strikethrough: { type: \"boolean\", description: \"Strikethrough text\", optional: true },\r\n fontSize: { type: \"number\", description: \"Font size in points\", optional: true },\r\n fontFamily: { type: \"string\", description: \"Font family name\", optional: true },\r\n foregroundColor: {\r\n type: \"object\",\r\n description: \"Text color (RGB values 0-1)\",\r\n properties: {\r\n red: { type: \"number\", optional: true },\r\n green: { type: \"number\", optional: true },\r\n blue: { type: \"number\", optional: true }\r\n },\r\n optional: true\r\n }\r\n },\r\n required: [\"presentationId\", \"objectId\"]\r\n }\r\n },\r\n {\r\n name: \"formatGoogleSlidesParagraph\",\r\n description: \"Apply paragraph formatting to text in Google Slides\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n presentationId: { type: \"string\", description: \"Presentation ID\" },\r\n objectId: { type: \"string\", description: \"Object ID of the text element\" },\r\n alignment: {\r\n type: \"string\",\r\n description: \"Text alignment\",\r\n enum: [\"START\", \"CENTER\", \"END\", \"JUSTIFIED\"],\r\n optional: true\r\n },\r\n lineSpacing: { type: \"number\", description: \"Line spacing multiplier\", optional: true },\r\n bulletStyle: {\r\n type: \"string\",\r\n description: \"Bullet style\",\r\n enum: [\"NONE\", \"DISC\", \"ARROW\", \"SQUARE\", \"DIAMOND\", \"STAR\", \"NUMBERED\"],\r\n optional: true\r\n }\r\n },\r\n required: [\"presentationId\", \"objectId\"]\r\n }\r\n },\r\n {\r\n name: \"styleGoogleSlidesShape\",\r\n description: \"Style shapes in Google Slides\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n presentationId: { type: \"string\", description: \"Presentation ID\" },\r\n objectId: { type: \"string\", description: \"Shape object ID\" },\r\n backgroundColor: {\r\n type: \"object\",\r\n description: \"Background color (RGBA values 0-1)\",\r\n properties: {\r\n red: { type: \"number\", optional: true },\r\n green: { type: \"number\", optional: true },\r\n blue: { type: \"number\", optional: true },\r\n alpha: { type: \"number\", optional: true }\r\n },\r\n optional: true\r\n },\r\n outlineColor: {\r\n type: \"object\",\r\n description: \"Outline color (RGB values 0-1)\",\r\n properties: {\r\n red: { type: \"number\", optional: true },\r\n green: { type: \"number\", optional: true },\r\n blue: { type: \"number\", optional: true }\r\n },\r\n optional: true\r\n },\r\n outlineWeight: { type: \"number\", description: \"Outline thickness in points\", optional: true },\r\n outlineDashStyle: {\r\n type: \"string\",\r\n description: \"Outline dash style\",\r\n enum: [\"SOLID\", \"DOT\", \"DASH\", \"DASH_DOT\", \"LONG_DASH\", \"LONG_DASH_DOT\"],\r\n optional: true\r\n }\r\n },\r\n required: [\"presentationId\", \"objectId\"]\r\n }\r\n },\r\n {\r\n name: \"setGoogleSlidesBackground\",\r\n description: \"Set background color for slides\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n presentationId: { type: \"string\", description: \"Presentation ID\" },\r\n pageObjectIds: {\r\n type: \"array\",\r\n description: \"Array of slide IDs to update\",\r\n items: { type: \"string\" }\r\n },\r\n backgroundColor: {\r\n type: \"object\",\r\n description: \"Background color (RGBA values 0-1)\",\r\n properties: {\r\n red: { type: \"number\", optional: true },\r\n green: { type: \"number\", optional: true },\r\n blue: { type: \"number\", optional: true },\r\n alpha: { type: \"number\", optional: true }\r\n }\r\n }\r\n },\r\n required: [\"presentationId\", \"pageObjectIds\", \"backgroundColor\"]\r\n }\r\n },\r\n {\r\n name: \"createGoogleSlidesTextBox\",\r\n description: \"Create a text box in Google Slides\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n presentationId: { type: \"string\", description: \"Presentation ID\" },\r\n pageObjectId: { type: \"string\", description: \"Slide ID\" },\r\n text: { type: \"string\", description: \"Text content\" },\r\n x: { type: \"number\", description: \"X position in EMU (1/360000 cm)\" },\r\n y: { type: \"number\", description: \"Y position in EMU\" },\r\n width: { type: \"number\", description: \"Width in EMU\" },\r\n height: { type: \"number\", description: \"Height in EMU\" },\r\n fontSize: { type: \"number\", description: \"Font size in points\", optional: true },\r\n bold: { type: \"boolean\", description: \"Make text bold\", optional: true },\r\n italic: { type: \"boolean\", description: \"Make text italic\", optional: true }\r\n },\r\n required: [\"presentationId\", \"pageObjectId\", \"text\", \"x\", \"y\", \"width\", \"height\"]\r\n }\r\n },\r\n {\r\n name: \"createGoogleSlidesShape\",\r\n description: \"Create a shape in Google Slides\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n presentationId: { type: \"string\", description: \"Presentation ID\" },\r\n pageObjectId: { type: \"string\", description: \"Slide ID\" },\r\n shapeType: {\r\n type: \"string\",\r\n description: \"Shape type\",\r\n enum: [\"RECTANGLE\", \"ELLIPSE\", \"DIAMOND\", \"TRIANGLE\", \"STAR\", \"ROUND_RECTANGLE\", \"ARROW\"]\r\n },\r\n x: { type: \"number\", description: \"X position in EMU\" },\r\n y: { type: \"number\", description: \"Y position in EMU\" },\r\n width: { type: \"number\", description: \"Width in EMU\" },\r\n height: { type: \"number\", description: \"Height in EMU\" },\r\n backgroundColor: {\r\n type: \"object\",\r\n description: \"Fill color (RGBA values 0-1)\",\r\n properties: {\r\n red: { type: \"number\", optional: true },\r\n green: { type: \"number\", optional: true },\r\n blue: { type: \"number\", optional: true },\r\n alpha: { type: \"number\", optional: true }\r\n },\r\n optional: true\r\n }\r\n },\r\n required: [\"presentationId\", \"pageObjectId\", \"shapeType\", \"x\", \"y\", \"width\", \"height\"]\r\n }\r\n }\r\n ]\r\n };\r\n});\r\n\r\n// -----------------------------------------------------------------------------\r\n// TOOL CALL REQUEST HANDLER\r\n// -----------------------------------------------------------------------------\r\n\r\nserver.setRequestHandler(CallToolRequestSchema, async (request) => {\r\n console.error(`[DEBUG] CallTool handler called for tool: ${request.params.name}`);\r\n await ensureAuthenticated();\r\n console.error(`[DEBUG] After ensureAuthenticated - authClient exists: ${!!authClient}, drive exists: ${!!drive}`);\r\n log('Handling tool request', { tool: request.params.name });\r\n\r\n // Helper for error responses\r\n function errorResponse(message: string) {\r\n log('Error', { message });\r\n return { content: [{ type: \"text\", text: `Error: ${message}` }], isError: true };\r\n }\r\n\r\n try {\r\n switch (request.params.name) {\r\n case \"search\": {\r\n const validation = SearchSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const { query: userQuery, pageSize, pageToken } = validation.data;\r\n\r\n const escapedQuery = userQuery.replace(/\\\\/g, \"\\\\\\\\\").replace(/'/g, \"\\\\'\");\r\n const formattedQuery = `fullText contains '${escapedQuery}' and trashed = false`;\r\n\r\n const res = await drive.files.list({\r\n q: formattedQuery,\r\n pageSize: Math.min(pageSize || 50, 100),\r\n pageToken: pageToken,\r\n fields: \"nextPageToken, files(id, name, mimeType, modifiedTime, size)\",\r\n });\r\n\r\n const fileList = res.data.files?.map((f: drive_v3.Schema$File) => `${f.name} (${f.mimeType})`).join(\"\\n\") || '';\r\n log('Search results', { query: userQuery, resultCount: res.data.files?.length });\r\n\r\n let response = `Found ${res.data.files?.length ?? 0} files:\\n${fileList}`;\r\n if (res.data.nextPageToken) {\r\n response += `\\n\\nMore results available. Use pageToken: ${res.data.nextPageToken}`;\r\n }\r\n\r\n return {\r\n content: [{ type: \"text\", text: response }],\r\n isError: false,\r\n };\r\n }\r\n\r\n case \"createTextFile\": {\r\n const validation = CreateTextFileSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n validateTextFileExtension(args.name);\r\n const parentFolderId = await resolveFolderId(args.parentFolderId);\r\n\r\n // Check if file already exists\r\n const existingFileId = await checkFileExists(args.name, parentFolderId);\r\n if (existingFileId) {\r\n return errorResponse(\r\n `A file named \"${args.name}\" already exists in this location. ` +\r\n `To update it, use updateTextFile with fileId: ${existingFileId}`\r\n );\r\n }\r\n\r\n const fileMetadata = {\r\n name: args.name,\r\n mimeType: getMimeTypeFromFilename(args.name),\r\n parents: [parentFolderId]\r\n };\r\n\r\n log('About to create file', {\r\n driveExists: !!drive,\r\n authClientExists: !!authClient,\r\n hasAccessToken: !!authClient?.credentials?.access_token,\r\n tokenLength: authClient?.credentials?.access_token?.length\r\n });\r\n\r\n const file = await drive.files.create({\r\n requestBody: fileMetadata,\r\n media: {\r\n mimeType: fileMetadata.mimeType,\r\n body: args.content,\r\n },\r\n });\r\n\r\n log('File created successfully', { fileId: file.data?.id });\r\n return {\r\n content: [{\r\n type: \"text\",\r\n text: `Created file: ${file.data?.name || args.name}\\nID: ${file.data?.id || 'unknown'}`\r\n }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"updateTextFile\": {\r\n const validation = UpdateTextFileSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n // Check file MIME type\r\n const existingFile = await drive.files.get({\r\n fileId: args.fileId,\r\n fields: 'mimeType, name, parents'\r\n });\r\n\r\n const currentMimeType = existingFile.data.mimeType || 'text/plain';\r\n if (!Object.values(TEXT_MIME_TYPES).includes(currentMimeType)) {\r\n return errorResponse(\"File is not a text or markdown file.\");\r\n }\r\n\r\n const updateMetadata: { name?: string; mimeType?: string } = {};\r\n if (args.name) {\r\n validateTextFileExtension(args.name);\r\n updateMetadata.name = args.name;\r\n updateMetadata.mimeType = getMimeTypeFromFilename(args.name);\r\n }\r\n\r\n const updatedFile = await drive.files.update({\r\n fileId: args.fileId,\r\n requestBody: updateMetadata,\r\n media: {\r\n mimeType: updateMetadata.mimeType || currentMimeType,\r\n body: args.content\r\n },\r\n fields: 'id, name, modifiedTime, webViewLink'\r\n });\r\n\r\n return {\r\n content: [{\r\n type: \"text\",\r\n text: `Updated file: ${updatedFile.data.name}\\nModified: ${updatedFile.data.modifiedTime}`\r\n }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"createFolder\": {\r\n const validation = CreateFolderSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const parentFolderId = await resolveFolderId(args.parent);\r\n\r\n // Check if folder already exists\r\n const existingFolderId = await checkFileExists(args.name, parentFolderId);\r\n if (existingFolderId) {\r\n return errorResponse(\r\n `A folder named \"${args.name}\" already exists in this location. ` +\r\n `Folder ID: ${existingFolderId}`\r\n );\r\n }\r\n const folderMetadata = {\r\n name: args.name,\r\n mimeType: FOLDER_MIME_TYPE,\r\n parents: [parentFolderId]\r\n };\r\n\r\n const folder = await drive.files.create({\r\n requestBody: folderMetadata,\r\n fields: 'id, name, webViewLink'\r\n });\r\n\r\n log('Folder created successfully', { folderId: folder.data.id, name: folder.data.name });\r\n\r\n return {\r\n content: [{\r\n type: \"text\",\r\n text: `Created folder: ${folder.data.name}\\nID: ${folder.data.id}`\r\n }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"listFolder\": {\r\n const validation = ListFolderSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n // Default to root if no folder specified\r\n const targetFolderId = args.folderId || 'root';\r\n\r\n const res = await drive.files.list({\r\n q: `'${targetFolderId}' in parents and trashed = false`,\r\n pageSize: Math.min(args.pageSize || 50, 100),\r\n pageToken: args.pageToken,\r\n fields: \"nextPageToken, files(id, name, mimeType, modifiedTime, size)\",\r\n orderBy: \"name\"\r\n });\r\n\r\n const files = res.data.files || [];\r\n const formattedFiles = files.map((file: drive_v3.Schema$File) => {\r\n const isFolder = file.mimeType === FOLDER_MIME_TYPE;\r\n return `${isFolder ? '\uD83D\uDCC1' : '\uD83D\uDCC4'} ${file.name} (ID: ${file.id})`;\r\n }).join('\\n');\r\n\r\n let response = `Contents of folder:\\n\\n${formattedFiles}`;\r\n if (res.data.nextPageToken) {\r\n response += `\\n\\nMore items available. Use pageToken: ${res.data.nextPageToken}`;\r\n }\r\n\r\n return {\r\n content: [{ type: \"text\", text: response }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"deleteItem\": {\r\n const validation = DeleteItemSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const item = await drive.files.get({ fileId: args.itemId, fields: 'name' });\r\n \r\n // Move to trash instead of permanent deletion\r\n await drive.files.update({\r\n fileId: args.itemId,\r\n requestBody: {\r\n trashed: true\r\n }\r\n });\r\n\r\n log('Item moved to trash successfully', { itemId: args.itemId, name: item.data.name });\r\n return {\r\n content: [{ type: \"text\", text: `Successfully moved to trash: ${item.data.name}` }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"renameItem\": {\r\n const validation = RenameItemSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n // If it's a text file, check extension\r\n const item = await drive.files.get({ fileId: args.itemId, fields: 'name, mimeType' });\r\n if (Object.values(TEXT_MIME_TYPES).includes(item.data.mimeType || '')) {\r\n validateTextFileExtension(args.newName);\r\n }\r\n\r\n const updatedItem = await drive.files.update({\r\n fileId: args.itemId,\r\n requestBody: { name: args.newName },\r\n fields: 'id, name, modifiedTime'\r\n });\r\n\r\n return {\r\n content: [{\r\n type: \"text\",\r\n text: `Successfully renamed \"${item.data.name}\" to \"${updatedItem.data.name}\"`\r\n }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"moveItem\": {\r\n const validation = MoveItemSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const destinationFolderId = args.destinationFolderId ?\r\n await resolveFolderId(args.destinationFolderId) :\r\n 'root';\r\n\r\n // Check we aren't moving a folder into itself or its descendant\r\n if (args.destinationFolderId === args.itemId) {\r\n return errorResponse(\"Cannot move a folder into itself.\");\r\n }\r\n\r\n const item = await drive.files.get({ fileId: args.itemId, fields: 'name, parents' });\r\n\r\n // Perform move\r\n await drive.files.update({\r\n fileId: args.itemId,\r\n addParents: destinationFolderId,\r\n removeParents: item.data.parents?.join(',') || '',\r\n fields: 'id, name, parents'\r\n });\r\n\r\n // Get the destination folder name for a nice response\r\n const destinationFolder = await drive.files.get({\r\n fileId: destinationFolderId,\r\n fields: 'name'\r\n });\r\n\r\n return {\r\n content: [{\r\n type: \"text\",\r\n text: `Successfully moved \"${item.data.name}\" to \"${destinationFolder.data.name}\"`\r\n }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"createGoogleDoc\": {\r\n const validation = CreateGoogleDocSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const parentFolderId = await resolveFolderId(args.parentFolderId);\r\n\r\n // Check if document already exists\r\n const existingFileId = await checkFileExists(args.name, parentFolderId);\r\n if (existingFileId) {\r\n return errorResponse(\r\n `A document named \"${args.name}\" already exists in this location. ` +\r\n `To update it, use updateGoogleDoc with documentId: ${existingFileId}`\r\n );\r\n }\r\n\r\n log('Creating Google Doc', { \r\n authClientExists: !!authClient, \r\n parentFolderId,\r\n authClientType: authClient?.constructor?.name,\r\n accessToken: authClient?.credentials?.access_token ? 'present' : 'missing',\r\n tokenLength: authClient?.credentials?.access_token?.length\r\n });\r\n\r\n // Debug: Try to get current user to verify auth\r\n try {\r\n const aboutResponse = await drive.about.get({ fields: 'user' });\r\n log('Auth verification - current user:', aboutResponse.data.user?.emailAddress);\r\n } catch (authError) {\r\n log('Auth verification failed:', authError instanceof Error ? authError.message : String(authError));\r\n }\r\n\r\n // Create empty doc\r\n let docResponse;\r\n try {\r\n docResponse = await drive.files.create({\r\n requestBody: {\r\n name: args.name,\r\n mimeType: 'application/vnd.google-apps.document',\r\n parents: [parentFolderId]\r\n },\r\n fields: 'id, name, webViewLink'\r\n });\r\n } catch (createError: any) {\r\n log('Drive files.create error details:', {\r\n message: createError.message,\r\n code: createError.code,\r\n errors: createError.errors,\r\n status: createError.status\r\n });\r\n throw createError;\r\n }\r\n const doc = docResponse.data;\r\n\r\n const docs = google.docs({ version: 'v1', auth: authClient });\r\n await docs.documents.batchUpdate({\r\n documentId: doc.id!,\r\n requestBody: {\r\n requests: [\r\n {\r\n insertText: { location: { index: 1 }, text: args.content }\r\n },\r\n // Ensure the text is formatted as normal text, not as a header\r\n {\r\n updateParagraphStyle: {\r\n range: {\r\n startIndex: 1,\r\n endIndex: args.content.length + 1\r\n },\r\n paragraphStyle: {\r\n namedStyleType: 'NORMAL_TEXT'\r\n },\r\n fields: 'namedStyleType'\r\n }\r\n }\r\n ]\r\n }\r\n });\r\n\r\n return {\r\n content: [{ type: \"text\", text: `Created Google Doc: ${doc.name}\\nID: ${doc.id}\\nLink: ${doc.webViewLink}` }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"updateGoogleDoc\": {\r\n const validation = UpdateGoogleDocSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const docs = google.docs({ version: 'v1', auth: authClient });\r\n const document = await docs.documents.get({ documentId: args.documentId });\r\n\r\n // Delete all content\r\n // End index of last piece of content (body's last element, fallback to 1 if none)\r\n const endIndex = document.data.body?.content?.[document.data.body.content.length - 1]?.endIndex || 1;\r\n \r\n // Google Docs API doesn't allow deleting the final newline character\r\n // We need to leave at least one character in the document\r\n const deleteEndIndex = Math.max(1, endIndex - 1);\r\n\r\n if (deleteEndIndex > 1) {\r\n await docs.documents.batchUpdate({\r\n documentId: args.documentId,\r\n requestBody: {\r\n requests: [{\r\n deleteContentRange: {\r\n range: { startIndex: 1, endIndex: deleteEndIndex }\r\n }\r\n }]\r\n }\r\n });\r\n }\r\n\r\n // Insert new content\r\n await docs.documents.batchUpdate({\r\n documentId: args.documentId,\r\n requestBody: {\r\n requests: [\r\n {\r\n insertText: { location: { index: 1 }, text: args.content }\r\n },\r\n // Ensure the text is formatted as normal text, not as a header\r\n {\r\n updateParagraphStyle: {\r\n range: {\r\n startIndex: 1,\r\n endIndex: args.content.length + 1\r\n },\r\n paragraphStyle: {\r\n namedStyleType: 'NORMAL_TEXT'\r\n },\r\n fields: 'namedStyleType'\r\n }\r\n }\r\n ]\r\n }\r\n });\r\n\r\n return {\r\n content: [{ type: \"text\", text: `Updated Google Doc: ${document.data.title}` }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"createGoogleSheet\": {\r\n const validation = CreateGoogleSheetSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const parentFolderId = await resolveFolderId(args.parentFolderId);\r\n\r\n // Check if spreadsheet already exists\r\n const existingFileId = await checkFileExists(args.name, parentFolderId);\r\n if (existingFileId) {\r\n return errorResponse(\r\n `A spreadsheet named \"${args.name}\" already exists in this location. ` +\r\n `To update it, use updateGoogleSheet with spreadsheetId: ${existingFileId}`\r\n );\r\n }\r\n const sheets = google.sheets({ version: 'v4', auth: authClient });\r\n \r\n // Create spreadsheet with initial sheet\r\n const spreadsheet = await sheets.spreadsheets.create({\r\n requestBody: { \r\n properties: { title: args.name },\r\n sheets: [{\r\n properties: {\r\n sheetId: 0,\r\n title: 'Sheet1',\r\n gridProperties: {\r\n rowCount: Math.max(args.data.length, 1000),\r\n columnCount: Math.max(args.data[0]?.length || 0, 26)\r\n }\r\n }\r\n }]\r\n }\r\n });\r\n\r\n await drive.files.update({\r\n fileId: spreadsheet.data.spreadsheetId || '',\r\n addParents: parentFolderId,\r\n fields: 'id, name, webViewLink'\r\n });\r\n\r\n // Now update with data\r\n await sheets.spreadsheets.values.update({\r\n spreadsheetId: spreadsheet.data.spreadsheetId!,\r\n range: 'Sheet1!A1',\r\n valueInputOption: 'RAW',\r\n requestBody: { values: args.data }\r\n });\r\n\r\n return {\r\n content: [{ type: \"text\", text: `Created Google Sheet: ${args.name}\\nID: ${spreadsheet.data.spreadsheetId}` }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"updateGoogleSheet\": {\r\n const validation = UpdateGoogleSheetSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const sheets = google.sheets({ version: 'v4', auth: authClient });\r\n await sheets.spreadsheets.values.update({\r\n spreadsheetId: args.spreadsheetId,\r\n range: args.range,\r\n valueInputOption: 'RAW',\r\n requestBody: { values: args.data }\r\n });\r\n\r\n return {\r\n content: [{ type: \"text\", text: `Updated Google Sheet range: ${args.range}` }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"getGoogleSheetContent\": {\r\n const validation = GetGoogleSheetContentSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const sheets = google.sheets({ version: 'v4', auth: authClient });\r\n const response = await sheets.spreadsheets.values.get({\r\n spreadsheetId: args.spreadsheetId,\r\n range: args.range\r\n });\r\n\r\n const values = response.data.values || [];\r\n let content = `Content for range ${args.range}:\\n\\n`;\r\n \r\n if (values.length === 0) {\r\n content += \"(empty range)\";\r\n } else {\r\n values.forEach((row, rowIndex) => {\r\n content += `Row ${rowIndex + 1}: ${row.join(', ')}\\n`;\r\n });\r\n }\r\n\r\n return {\r\n content: [{ type: \"text\", text: content }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"formatGoogleSheetCells\": {\r\n const validation = FormatGoogleSheetCellsSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const sheets = google.sheets({ version: 'v4', auth: authClient });\r\n \r\n // Parse the range to get sheet ID and grid range\r\n const rangeData = await sheets.spreadsheets.get({\r\n spreadsheetId: args.spreadsheetId,\r\n ranges: [args.range],\r\n fields: 'sheets(properties(sheetId,title))'\r\n });\r\n\r\n console.error(`[DEBUG] formatGoogleSheetCells - range: ${args.range}`);\r\n console.error(`[DEBUG] rangeData.data:`, JSON.stringify(rangeData.data, null, 2));\r\n \r\n const sheetName = args.range.includes('!') ? args.range.split('!')[0] : 'Sheet1';\r\n console.error(`[DEBUG] Calculated sheetName: \"${sheetName}\"`);\r\n \r\n const sheet = rangeData.data.sheets?.find(s => s.properties?.title === sheetName);\r\n console.error(`[DEBUG] Found sheet:`, sheet ? JSON.stringify(sheet, null, 2) : 'null');\r\n \r\n if (!sheet || sheet.properties?.sheetId === undefined || sheet.properties?.sheetId === null) {\r\n console.error(`[DEBUG] Available sheets:`, rangeData.data.sheets?.map(s => s.properties?.title).join(', '));\r\n return errorResponse(`Sheet \"${sheetName}\" not found`);\r\n }\r\n\r\n // Parse A1 notation to grid range\r\n const a1Range = args.range.includes('!') ? args.range.split('!')[1] : args.range;\r\n const gridRange = convertA1ToGridRange(a1Range, sheet.properties.sheetId!);\r\n\r\n const requests: any[] = [{\r\n repeatCell: {\r\n range: gridRange,\r\n cell: {\r\n userEnteredFormat: {\r\n ...(args.backgroundColor && {\r\n backgroundColor: {\r\n red: args.backgroundColor.red || 0,\r\n green: args.backgroundColor.green || 0,\r\n blue: args.backgroundColor.blue || 0\r\n }\r\n }),\r\n ...(args.horizontalAlignment && { horizontalAlignment: args.horizontalAlignment }),\r\n ...(args.verticalAlignment && { verticalAlignment: args.verticalAlignment }),\r\n ...(args.wrapStrategy && { wrapStrategy: args.wrapStrategy })\r\n }\r\n },\r\n fields: [\r\n args.backgroundColor && 'userEnteredFormat.backgroundColor',\r\n args.horizontalAlignment && 'userEnteredFormat.horizontalAlignment',\r\n args.verticalAlignment && 'userEnteredFormat.verticalAlignment',\r\n args.wrapStrategy && 'userEnteredFormat.wrapStrategy'\r\n ].filter(Boolean).join(',')\r\n }\r\n }];\r\n\r\n await sheets.spreadsheets.batchUpdate({\r\n spreadsheetId: args.spreadsheetId,\r\n requestBody: { requests }\r\n });\r\n\r\n return {\r\n content: [{ type: \"text\", text: `Formatted cells in range ${args.range}` }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"formatGoogleSheetText\": {\r\n const validation = FormatGoogleSheetTextSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const sheets = google.sheets({ version: 'v4', auth: authClient });\r\n \r\n // Get sheet information\r\n const rangeData = await sheets.spreadsheets.get({\r\n spreadsheetId: args.spreadsheetId,\r\n ranges: [args.range],\r\n fields: 'sheets(properties(sheetId,title))'\r\n });\r\n\r\n const sheetName = args.range.includes('!') ? args.range.split('!')[0] : 'Sheet1';\r\n const sheet = rangeData.data.sheets?.find(s => s.properties?.title === sheetName);\r\n if (!sheet || sheet.properties?.sheetId === undefined || sheet.properties?.sheetId === null) {\r\n return errorResponse(`Sheet \"${sheetName}\" not found`);\r\n }\r\n\r\n const a1Range = args.range.includes('!') ? args.range.split('!')[1] : args.range;\r\n const gridRange = convertA1ToGridRange(a1Range, sheet.properties.sheetId!);\r\n\r\n const textFormat: any = {};\r\n const fields: string[] = [];\r\n\r\n if (args.bold !== undefined) {\r\n textFormat.bold = args.bold;\r\n fields.push('bold');\r\n }\r\n if (args.italic !== undefined) {\r\n textFormat.italic = args.italic;\r\n fields.push('italic');\r\n }\r\n if (args.strikethrough !== undefined) {\r\n textFormat.strikethrough = args.strikethrough;\r\n fields.push('strikethrough');\r\n }\r\n if (args.underline !== undefined) {\r\n textFormat.underline = args.underline;\r\n fields.push('underline');\r\n }\r\n if (args.fontSize !== undefined) {\r\n textFormat.fontSize = args.fontSize;\r\n fields.push('fontSize');\r\n }\r\n if (args.fontFamily !== undefined) {\r\n textFormat.fontFamily = args.fontFamily;\r\n fields.push('fontFamily');\r\n }\r\n if (args.foregroundColor) {\r\n textFormat.foregroundColor = {\r\n red: args.foregroundColor.red || 0,\r\n green: args.foregroundColor.green || 0,\r\n blue: args.foregroundColor.blue || 0\r\n };\r\n fields.push('foregroundColor');\r\n }\r\n\r\n const requests = [{\r\n repeatCell: {\r\n range: gridRange,\r\n cell: {\r\n userEnteredFormat: { textFormat }\r\n },\r\n fields: 'userEnteredFormat.textFormat(' + fields.join(',') + ')'\r\n }\r\n }];\r\n\r\n await sheets.spreadsheets.batchUpdate({\r\n spreadsheetId: args.spreadsheetId,\r\n requestBody: { requests }\r\n });\r\n\r\n return {\r\n content: [{ type: \"text\", text: `Applied text formatting to range ${args.range}` }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"formatGoogleSheetNumbers\": {\r\n const validation = FormatGoogleSheetNumbersSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const sheets = google.sheets({ version: 'v4', auth: authClient });\r\n \r\n const rangeData = await sheets.spreadsheets.get({\r\n spreadsheetId: args.spreadsheetId,\r\n ranges: [args.range],\r\n fields: 'sheets(properties(sheetId,title))'\r\n });\r\n\r\n const sheetName = args.range.includes('!') ? args.range.split('!')[0] : 'Sheet1';\r\n const sheet = rangeData.data.sheets?.find(s => s.properties?.title === sheetName);\r\n if (!sheet || sheet.properties?.sheetId === undefined || sheet.properties?.sheetId === null) {\r\n return errorResponse(`Sheet \"${sheetName}\" not found`);\r\n }\r\n\r\n const a1Range = args.range.includes('!') ? args.range.split('!')[1] : args.range;\r\n const gridRange = convertA1ToGridRange(a1Range, sheet.properties.sheetId!);\r\n\r\n const numberFormat: any = {\r\n pattern: args.pattern\r\n };\r\n if (args.type) {\r\n numberFormat.type = args.type;\r\n }\r\n\r\n const requests = [{\r\n repeatCell: {\r\n range: gridRange,\r\n cell: {\r\n userEnteredFormat: { numberFormat }\r\n },\r\n fields: 'userEnteredFormat.numberFormat'\r\n }\r\n }];\r\n\r\n await sheets.spreadsheets.batchUpdate({\r\n spreadsheetId: args.spreadsheetId,\r\n requestBody: { requests }\r\n });\r\n\r\n return {\r\n content: [{ type: \"text\", text: `Applied number formatting to range ${args.range}` }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"setGoogleSheetBorders\": {\r\n const validation = SetGoogleSheetBordersSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const sheets = google.sheets({ version: 'v4', auth: authClient });\r\n \r\n const rangeData = await sheets.spreadsheets.get({\r\n spreadsheetId: args.spreadsheetId,\r\n ranges: [args.range],\r\n fields: 'sheets(properties(sheetId,title))'\r\n });\r\n\r\n const sheetName = args.range.includes('!') ? args.range.split('!')[0] : 'Sheet1';\r\n const sheet = rangeData.data.sheets?.find(s => s.properties?.title === sheetName);\r\n if (!sheet || sheet.properties?.sheetId === undefined || sheet.properties?.sheetId === null) {\r\n return errorResponse(`Sheet \"${sheetName}\" not found`);\r\n }\r\n\r\n const a1Range = args.range.includes('!') ? args.range.split('!')[1] : args.range;\r\n const gridRange = convertA1ToGridRange(a1Range, sheet.properties.sheetId!);\r\n\r\n const border = {\r\n style: args.style,\r\n width: args.width || 1,\r\n color: args.color ? {\r\n red: args.color.red || 0,\r\n green: args.color.green || 0,\r\n blue: args.color.blue || 0\r\n } : undefined\r\n };\r\n\r\n const updateBordersRequest: any = {\r\n updateBorders: {\r\n range: gridRange\r\n }\r\n };\r\n\r\n if (args.top !== false) updateBordersRequest.updateBorders.top = border;\r\n if (args.bottom !== false) updateBordersRequest.updateBorders.bottom = border;\r\n if (args.left !== false) updateBordersRequest.updateBorders.left = border;\r\n if (args.right !== false) updateBordersRequest.updateBorders.right = border;\r\n if (args.innerHorizontal) updateBordersRequest.updateBorders.innerHorizontal = border;\r\n if (args.innerVertical) updateBordersRequest.updateBorders.innerVertical = border;\r\n\r\n await sheets.spreadsheets.batchUpdate({\r\n spreadsheetId: args.spreadsheetId,\r\n requestBody: { requests: [updateBordersRequest] }\r\n });\r\n\r\n return {\r\n content: [{ type: \"text\", text: `Set borders for range ${args.range}` }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"mergeGoogleSheetCells\": {\r\n const validation = MergeGoogleSheetCellsSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const sheets = google.sheets({ version: 'v4', auth: authClient });\r\n \r\n const rangeData = await sheets.spreadsheets.get({\r\n spreadsheetId: args.spreadsheetId,\r\n ranges: [args.range],\r\n fields: 'sheets(properties(sheetId,title))'\r\n });\r\n\r\n const sheetName = args.range.includes('!') ? args.range.split('!')[0] : 'Sheet1';\r\n const sheet = rangeData.data.sheets?.find(s => s.properties?.title === sheetName);\r\n if (!sheet || sheet.properties?.sheetId === undefined || sheet.properties?.sheetId === null) {\r\n return errorResponse(`Sheet \"${sheetName}\" not found`);\r\n }\r\n\r\n const a1Range = args.range.includes('!') ? args.range.split('!')[1] : args.range;\r\n const gridRange = convertA1ToGridRange(a1Range, sheet.properties.sheetId!);\r\n\r\n const requests = [{\r\n mergeCells: {\r\n range: gridRange,\r\n mergeType: args.mergeType\r\n }\r\n }];\r\n\r\n await sheets.spreadsheets.batchUpdate({\r\n spreadsheetId: args.spreadsheetId,\r\n requestBody: { requests }\r\n });\r\n\r\n return {\r\n content: [{ type: \"text\", text: `Merged cells in range ${args.range} with type ${args.mergeType}` }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"addGoogleSheetConditionalFormat\": {\r\n const validation = AddGoogleSheetConditionalFormatSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const sheets = google.sheets({ version: 'v4', auth: authClient });\r\n \r\n const rangeData = await sheets.spreadsheets.get({\r\n spreadsheetId: args.spreadsheetId,\r\n ranges: [args.range],\r\n fields: 'sheets(properties(sheetId,title))'\r\n });\r\n\r\n const sheetName = args.range.includes('!') ? args.range.split('!')[0] : 'Sheet1';\r\n const sheet = rangeData.data.sheets?.find(s => s.properties?.title === sheetName);\r\n if (!sheet || sheet.properties?.sheetId === undefined || sheet.properties?.sheetId === null) {\r\n return errorResponse(`Sheet \"${sheetName}\" not found`);\r\n }\r\n\r\n const a1Range = args.range.includes('!') ? args.range.split('!')[1] : args.range;\r\n const gridRange = convertA1ToGridRange(a1Range, sheet.properties.sheetId!);\r\n\r\n // Build condition based on type\r\n const booleanCondition: any = {};\r\n switch (args.condition.type) {\r\n case 'NUMBER_GREATER':\r\n booleanCondition.type = 'NUMBER_GREATER';\r\n booleanCondition.values = [{ userEnteredValue: args.condition.value }];\r\n break;\r\n case 'NUMBER_LESS':\r\n booleanCondition.type = 'NUMBER_LESS';\r\n booleanCondition.values = [{ userEnteredValue: args.condition.value }];\r\n break;\r\n case 'TEXT_CONTAINS':\r\n booleanCondition.type = 'TEXT_CONTAINS';\r\n booleanCondition.values = [{ userEnteredValue: args.condition.value }];\r\n break;\r\n case 'TEXT_STARTS_WITH':\r\n booleanCondition.type = 'TEXT_STARTS_WITH';\r\n booleanCondition.values = [{ userEnteredValue: args.condition.value }];\r\n break;\r\n case 'TEXT_ENDS_WITH':\r\n booleanCondition.type = 'TEXT_ENDS_WITH';\r\n booleanCondition.values = [{ userEnteredValue: args.condition.value }];\r\n break;\r\n case 'CUSTOM_FORMULA':\r\n booleanCondition.type = 'CUSTOM_FORMULA';\r\n booleanCondition.values = [{ userEnteredValue: args.condition.value }];\r\n break;\r\n }\r\n\r\n const format: any = {};\r\n if (args.format.backgroundColor) {\r\n format.backgroundColor = {\r\n red: args.format.backgroundColor.red || 0,\r\n green: args.format.backgroundColor.green || 0,\r\n blue: args.format.backgroundColor.blue || 0\r\n };\r\n }\r\n if (args.format.textFormat) {\r\n format.textFormat = {};\r\n if (args.format.textFormat.bold !== undefined) {\r\n format.textFormat.bold = args.format.textFormat.bold;\r\n }\r\n if (args.format.textFormat.foregroundColor) {\r\n format.textFormat.foregroundColor = {\r\n red: args.format.textFormat.foregroundColor.red || 0,\r\n green: args.format.textFormat.foregroundColor.green || 0,\r\n blue: args.format.textFormat.foregroundColor.blue || 0\r\n };\r\n }\r\n }\r\n\r\n const requests = [{\r\n addConditionalFormatRule: {\r\n rule: {\r\n ranges: [gridRange],\r\n booleanRule: {\r\n condition: booleanCondition,\r\n format: format\r\n }\r\n },\r\n index: 0\r\n }\r\n }];\r\n\r\n await sheets.spreadsheets.batchUpdate({\r\n spreadsheetId: args.spreadsheetId,\r\n requestBody: { requests }\r\n });\r\n\r\n return {\r\n content: [{ type: \"text\", text: `Added conditional formatting to range ${args.range}` }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"createGoogleSlides\": {\r\n const validation = CreateGoogleSlidesSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const parentFolderId = await resolveFolderId(args.parentFolderId);\r\n\r\n // Check if presentation already exists\r\n const existingFileId = await checkFileExists(args.name, parentFolderId);\r\n if (existingFileId) {\r\n return errorResponse(\r\n `A presentation named \"${args.name}\" already exists in this location. ` +\r\n `File ID: ${existingFileId}. To modify it, you can use Google Slides directly.`\r\n );\r\n }\r\n\r\n const slidesService = google.slides({ version: 'v1', auth: authClient });\r\n const presentation = await slidesService.presentations.create({\r\n requestBody: { title: args.name },\r\n });\r\n\r\n await drive.files.update({\r\n fileId: presentation.data.presentationId!,\r\n addParents: parentFolderId,\r\n removeParents: 'root',\r\n });\r\n\r\n for (const slide of args.slides) {\r\n const slideObjectId = `slide_${uuidv4().substring(0, 8)}`;\r\n await slidesService.presentations.batchUpdate({\r\n presentationId: presentation.data.presentationId!,\r\n requestBody: {\r\n requests: [{\r\n createSlide: {\r\n objectId: slideObjectId,\r\n slideLayoutReference: { predefinedLayout: 'TITLE_AND_BODY' },\r\n }\r\n }]\r\n },\r\n });\r\n\r\n const slidePage = await slidesService.presentations.pages.get({\r\n presentationId: presentation.data.presentationId!,\r\n pageObjectId: slideObjectId,\r\n });\r\n\r\n let titlePlaceholderId = '';\r\n let bodyPlaceholderId = '';\r\n slidePage.data.pageElements?.forEach((el) => {\r\n if (el.shape?.placeholder?.type === 'TITLE') {\r\n titlePlaceholderId = el.objectId!;\r\n } else if (el.shape?.placeholder?.type === 'BODY') {\r\n bodyPlaceholderId = el.objectId!;\r\n }\r\n });\r\n\r\n await slidesService.presentations.batchUpdate({\r\n presentationId: presentation.data.presentationId!,\r\n requestBody: {\r\n requests: [\r\n { insertText: { objectId: titlePlaceholderId, text: slide.title, insertionIndex: 0 } },\r\n { insertText: { objectId: bodyPlaceholderId, text: slide.content, insertionIndex: 0 } }\r\n ]\r\n },\r\n });\r\n }\r\n\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `Created Google Slides presentation: ${args.name}\\nID: ${presentation.data.presentationId}\\nLink: https://docs.google.com/presentation/d/${presentation.data.presentationId}`,\r\n }],\r\n isError: false,\r\n };\r\n }\r\n\r\n case \"updateGoogleSlides\": {\r\n const validation = UpdateGoogleSlidesSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const slidesService = google.slides({ version: 'v1', auth: authClient });\r\n \r\n // Get current presentation details\r\n const currentPresentation = await slidesService.presentations.get({\r\n presentationId: args.presentationId\r\n });\r\n \r\n if (!currentPresentation.data.slides) {\r\n return errorResponse(\"No slides found in presentation\");\r\n }\r\n\r\n // Collect all slide IDs except the first one (we'll keep it for now)\r\n const slideIdsToDelete = currentPresentation.data.slides\r\n .slice(1)\r\n .map(slide => slide.objectId)\r\n .filter((id): id is string => id !== undefined);\r\n\r\n // Prepare requests to update presentation\r\n const requests: any[] = [];\r\n\r\n // Delete all slides except the first one\r\n if (slideIdsToDelete.length > 0) {\r\n slideIdsToDelete.forEach(slideId => {\r\n requests.push({\r\n deleteObject: { objectId: slideId }\r\n });\r\n });\r\n }\r\n\r\n // Now we need to update the first slide or create new slides\r\n if (args.slides.length === 0) {\r\n return errorResponse(\"At least one slide must be provided\");\r\n }\r\n\r\n // Clear content of the first slide\r\n const firstSlide = currentPresentation.data.slides[0];\r\n if (firstSlide && firstSlide.pageElements) {\r\n // Find text elements to clear\r\n firstSlide.pageElements.forEach(element => {\r\n if (element.objectId && element.shape?.text) {\r\n requests.push({\r\n deleteText: {\r\n objectId: element.objectId,\r\n textRange: { type: 'ALL' }\r\n }\r\n });\r\n }\r\n });\r\n }\r\n\r\n // Update the first slide with new content\r\n const firstSlideContent = args.slides[0];\r\n if (firstSlide && firstSlide.pageElements) {\r\n // Find title and body placeholders\r\n let titlePlaceholderId: string | undefined;\r\n let bodyPlaceholderId: string | undefined;\r\n\r\n firstSlide.pageElements.forEach(element => {\r\n if (element.shape?.placeholder?.type === 'TITLE' || element.shape?.placeholder?.type === 'CENTERED_TITLE') {\r\n titlePlaceholderId = element.objectId || undefined;\r\n } else if (element.shape?.placeholder?.type === 'BODY' || element.shape?.placeholder?.type === 'SUBTITLE') {\r\n bodyPlaceholderId = element.objectId || undefined;\r\n }\r\n });\r\n\r\n if (titlePlaceholderId) {\r\n requests.push({\r\n insertText: {\r\n objectId: titlePlaceholderId,\r\n text: firstSlideContent.title,\r\n insertionIndex: 0\r\n }\r\n });\r\n }\r\n\r\n if (bodyPlaceholderId) {\r\n requests.push({\r\n insertText: {\r\n objectId: bodyPlaceholderId,\r\n text: firstSlideContent.content,\r\n insertionIndex: 0\r\n }\r\n });\r\n }\r\n }\r\n\r\n // Add any additional slides from the request\r\n for (let i = 1; i < args.slides.length; i++) {\r\n const slide = args.slides[i];\r\n const slideId = `slide_${Date.now()}_${i}`;\r\n \r\n requests.push({\r\n createSlide: {\r\n objectId: slideId,\r\n slideLayoutReference: {\r\n predefinedLayout: 'TITLE_AND_BODY'\r\n }\r\n }\r\n });\r\n\r\n // We'll need to add content to these slides in a separate batch update\r\n // because we need to wait for the slides to be created first\r\n }\r\n\r\n // Execute the batch update\r\n await slidesService.presentations.batchUpdate({\r\n presentationId: args.presentationId,\r\n requestBody: { requests }\r\n });\r\n\r\n // If we have additional slides, add their content\r\n if (args.slides.length > 1) {\r\n const contentRequests: any[] = [];\r\n \r\n // Get updated presentation to find the new slide IDs\r\n const updatedPresentation = await slidesService.presentations.get({\r\n presentationId: args.presentationId\r\n });\r\n\r\n // Add content to the new slides (starting from the second slide in our args)\r\n for (let i = 1; i < args.slides.length && updatedPresentation.data.slides; i++) {\r\n const slide = args.slides[i];\r\n const presentationSlide = updatedPresentation.data.slides[i];\r\n \r\n if (presentationSlide && presentationSlide.pageElements) {\r\n presentationSlide.pageElements.forEach(element => {\r\n if (element.objectId) {\r\n if (element.shape?.placeholder?.type === 'TITLE' || element.shape?.placeholder?.type === 'CENTERED_TITLE') {\r\n contentRequests.push({\r\n insertText: {\r\n objectId: element.objectId,\r\n text: slide.title,\r\n insertionIndex: 0\r\n }\r\n });\r\n } else if (element.shape?.placeholder?.type === 'BODY' || element.shape?.placeholder?.type === 'SUBTITLE') {\r\n contentRequests.push({\r\n insertText: {\r\n objectId: element.objectId,\r\n text: slide.content,\r\n insertionIndex: 0\r\n }\r\n });\r\n }\r\n }\r\n });\r\n }\r\n }\r\n\r\n if (contentRequests.length > 0) {\r\n await slidesService.presentations.batchUpdate({\r\n presentationId: args.presentationId,\r\n requestBody: { requests: contentRequests }\r\n });\r\n }\r\n }\r\n\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `Updated Google Slides presentation with ${args.slides.length} slide(s)\\nLink: https://docs.google.com/presentation/d/${args.presentationId}`,\r\n }],\r\n isError: false,\r\n };\r\n }\r\n\r\n case \"formatGoogleDocText\": {\r\n const validation = FormatGoogleDocTextSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const docs = google.docs({ version: 'v1', auth: authClient });\r\n \r\n // Build text style object\r\n const textStyle: any = {};\r\n const fields: string[] = [];\r\n \r\n if (args.bold !== undefined) {\r\n textStyle.bold = args.bold;\r\n fields.push('bold');\r\n }\r\n \r\n if (args.italic !== undefined) {\r\n textStyle.italic = args.italic;\r\n fields.push('italic');\r\n }\r\n \r\n if (args.underline !== undefined) {\r\n textStyle.underline = args.underline;\r\n fields.push('underline');\r\n }\r\n \r\n if (args.strikethrough !== undefined) {\r\n textStyle.strikethrough = args.strikethrough;\r\n fields.push('strikethrough');\r\n }\r\n \r\n if (args.fontSize !== undefined) {\r\n textStyle.fontSize = {\r\n magnitude: args.fontSize,\r\n unit: 'PT'\r\n };\r\n fields.push('fontSize');\r\n }\r\n \r\n if (args.foregroundColor) {\r\n textStyle.foregroundColor = {\r\n color: {\r\n rgbColor: {\r\n red: args.foregroundColor.red || 0,\r\n green: args.foregroundColor.green || 0,\r\n blue: args.foregroundColor.blue || 0\r\n }\r\n }\r\n };\r\n fields.push('foregroundColor');\r\n }\r\n \r\n if (fields.length === 0) {\r\n return errorResponse(\"No formatting options specified\");\r\n }\r\n \r\n await docs.documents.batchUpdate({\r\n documentId: args.documentId,\r\n requestBody: {\r\n requests: [{\r\n updateTextStyle: {\r\n range: {\r\n startIndex: args.startIndex,\r\n endIndex: args.endIndex\r\n },\r\n textStyle,\r\n fields: fields.join(',')\r\n }\r\n }]\r\n }\r\n });\r\n \r\n return {\r\n content: [{ type: \"text\", text: `Applied text formatting to range ${args.startIndex}-${args.endIndex}` }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"formatGoogleDocParagraph\": {\r\n const validation = FormatGoogleDocParagraphSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const docs = google.docs({ version: 'v1', auth: authClient });\r\n \r\n // Build paragraph style object\r\n const paragraphStyle: any = {};\r\n const fields: string[] = [];\r\n \r\n if (args.namedStyleType !== undefined) {\r\n paragraphStyle.namedStyleType = args.namedStyleType;\r\n fields.push('namedStyleType');\r\n }\r\n \r\n if (args.alignment !== undefined) {\r\n paragraphStyle.alignment = args.alignment;\r\n fields.push('alignment');\r\n }\r\n \r\n if (args.lineSpacing !== undefined) {\r\n paragraphStyle.lineSpacing = args.lineSpacing;\r\n fields.push('lineSpacing');\r\n }\r\n \r\n if (args.spaceAbove !== undefined) {\r\n paragraphStyle.spaceAbove = {\r\n magnitude: args.spaceAbove,\r\n unit: 'PT'\r\n };\r\n fields.push('spaceAbove');\r\n }\r\n \r\n if (args.spaceBelow !== undefined) {\r\n paragraphStyle.spaceBelow = {\r\n magnitude: args.spaceBelow,\r\n unit: 'PT'\r\n };\r\n fields.push('spaceBelow');\r\n }\r\n \r\n if (fields.length === 0) {\r\n return errorResponse(\"No formatting options specified\");\r\n }\r\n \r\n await docs.documents.batchUpdate({\r\n documentId: args.documentId,\r\n requestBody: {\r\n requests: [{\r\n updateParagraphStyle: {\r\n range: {\r\n startIndex: args.startIndex,\r\n endIndex: args.endIndex\r\n },\r\n paragraphStyle,\r\n fields: fields.join(',')\r\n }\r\n }]\r\n }\r\n });\r\n \r\n return {\r\n content: [{ type: \"text\", text: `Applied paragraph formatting to range ${args.startIndex}-${args.endIndex}` }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"getGoogleDocContent\": {\r\n const validation = GetGoogleDocContentSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const docs = google.docs({ version: 'v1', auth: authClient });\r\n const document = await docs.documents.get({ documentId: args.documentId });\r\n \r\n let content = '';\r\n let currentIndex = 1;\r\n const segments: Array<{text: string, startIndex: number, endIndex: number}> = [];\r\n \r\n // Extract text content with indices\r\n if (document.data.body?.content) {\r\n for (const element of document.data.body.content) {\r\n if (element.paragraph?.elements) {\r\n for (const textElement of element.paragraph.elements) {\r\n if (textElement.textRun?.content) {\r\n const text = textElement.textRun.content;\r\n segments.push({\r\n text,\r\n startIndex: currentIndex,\r\n endIndex: currentIndex + text.length\r\n });\r\n content += text;\r\n currentIndex += text.length;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n \r\n // Format the response to show text with indices\r\n let formattedContent = 'Document content with indices:\\n\\n';\r\n let lineStart = 1;\r\n const lines = content.split('\\n');\r\n \r\n for (let i = 0; i < lines.length; i++) {\r\n const line = lines[i];\r\n const lineEnd = lineStart + line.length;\r\n if (line.trim()) {\r\n formattedContent += `[${lineStart}-${lineEnd}] ${line}\\n`;\r\n }\r\n lineStart = lineEnd + 1; // +1 for the newline character\r\n }\r\n \r\n return {\r\n content: [{\r\n type: \"text\",\r\n text: formattedContent + `\\nTotal length: ${content.length} characters`\r\n }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"getGoogleSlidesContent\": {\r\n const validation = GetGoogleSlidesContentSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const slidesService = google.slides({ version: 'v1', auth: authClient });\r\n const presentation = await slidesService.presentations.get({\r\n presentationId: args.presentationId\r\n });\r\n\r\n if (!presentation.data.slides) {\r\n return errorResponse(\"No slides found in presentation\");\r\n }\r\n\r\n let content = 'Presentation content with element IDs:\\n\\n';\r\n const slides = args.slideIndex !== undefined \r\n ? [presentation.data.slides[args.slideIndex]]\r\n : presentation.data.slides;\r\n\r\n slides.forEach((slide, index) => {\r\n if (!slide || !slide.objectId) return;\r\n \r\n content += `\\nSlide ${args.slideIndex ?? index} (ID: ${slide.objectId}):\\n`;\r\n content += '----------------------------\\n';\r\n\r\n if (slide.pageElements) {\r\n slide.pageElements.forEach((element) => {\r\n if (!element.objectId) return;\r\n\r\n if (element.shape?.text) {\r\n content += ` Text Box (ID: ${element.objectId}):\\n`;\r\n const textElements = element.shape.text.textElements || [];\r\n let text = '';\r\n textElements.forEach((textElement) => {\r\n if (textElement.textRun?.content) {\r\n text += textElement.textRun.content;\r\n }\r\n });\r\n content += ` \"${text.trim()}\"\\n`;\r\n } else if (element.shape) {\r\n content += ` Shape (ID: ${element.objectId}): ${element.shape.shapeType || 'Unknown'}\\n`;\r\n } else if (element.image) {\r\n content += ` Image (ID: ${element.objectId})\\n`;\r\n } else if (element.video) {\r\n content += ` Video (ID: ${element.objectId})\\n`;\r\n } else if (element.table) {\r\n content += ` Table (ID: ${element.objectId})\\n`;\r\n }\r\n });\r\n }\r\n });\r\n\r\n return {\r\n content: [{ type: \"text\", text: content }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"formatGoogleSlidesText\": {\r\n const validation = FormatGoogleSlidesTextSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const slidesService = google.slides({ version: 'v1', auth: authClient });\r\n const textStyle: any = {};\r\n const fields: string[] = [];\r\n\r\n if (args.bold !== undefined) {\r\n textStyle.bold = args.bold;\r\n fields.push('bold');\r\n }\r\n\r\n if (args.italic !== undefined) {\r\n textStyle.italic = args.italic;\r\n fields.push('italic');\r\n }\r\n\r\n if (args.underline !== undefined) {\r\n textStyle.underline = args.underline;\r\n fields.push('underline');\r\n }\r\n\r\n if (args.strikethrough !== undefined) {\r\n textStyle.strikethrough = args.strikethrough;\r\n fields.push('strikethrough');\r\n }\r\n\r\n if (args.fontSize !== undefined) {\r\n textStyle.fontSize = {\r\n magnitude: args.fontSize,\r\n unit: 'PT'\r\n };\r\n fields.push('fontSize');\r\n }\r\n\r\n if (args.fontFamily !== undefined) {\r\n textStyle.fontFamily = args.fontFamily;\r\n fields.push('fontFamily');\r\n }\r\n\r\n if (args.foregroundColor) {\r\n textStyle.foregroundColor = {\r\n opaqueColor: {\r\n rgbColor: {\r\n red: args.foregroundColor.red || 0,\r\n green: args.foregroundColor.green || 0,\r\n blue: args.foregroundColor.blue || 0\r\n }\r\n }\r\n };\r\n fields.push('foregroundColor');\r\n }\r\n\r\n if (fields.length === 0) {\r\n return errorResponse(\"No formatting options specified\");\r\n }\r\n\r\n const updateRequest: any = {\r\n updateTextStyle: {\r\n objectId: args.objectId,\r\n style: textStyle,\r\n fields: fields.join(',')\r\n }\r\n };\r\n\r\n // Add text range if specified\r\n if (args.startIndex !== undefined && args.endIndex !== undefined) {\r\n updateRequest.updateTextStyle.textRange = {\r\n type: 'FIXED_RANGE',\r\n startIndex: args.startIndex,\r\n endIndex: args.endIndex\r\n };\r\n } else {\r\n updateRequest.updateTextStyle.textRange = { type: 'ALL' };\r\n }\r\n\r\n await slidesService.presentations.batchUpdate({\r\n presentationId: args.presentationId,\r\n requestBody: { requests: [updateRequest] }\r\n });\r\n\r\n return {\r\n content: [{ type: \"text\", text: `Applied text formatting to object ${args.objectId}` }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"formatGoogleSlidesParagraph\": {\r\n const validation = FormatGoogleSlidesParagraphSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const slidesService = google.slides({ version: 'v1', auth: authClient });\r\n const requests: any[] = [];\r\n\r\n if (args.alignment) {\r\n requests.push({\r\n updateParagraphStyle: {\r\n objectId: args.objectId,\r\n style: { alignment: args.alignment },\r\n fields: 'alignment'\r\n }\r\n });\r\n }\r\n\r\n if (args.lineSpacing !== undefined) {\r\n requests.push({\r\n updateParagraphStyle: {\r\n objectId: args.objectId,\r\n style: { lineSpacing: args.lineSpacing },\r\n fields: 'lineSpacing'\r\n }\r\n });\r\n }\r\n\r\n if (args.bulletStyle) {\r\n if (args.bulletStyle === 'NONE') {\r\n requests.push({\r\n deleteParagraphBullets: {\r\n objectId: args.objectId\r\n }\r\n });\r\n } else if (args.bulletStyle === 'NUMBERED') {\r\n requests.push({\r\n createParagraphBullets: {\r\n objectId: args.objectId,\r\n bulletPreset: 'NUMBERED_DIGIT_ALPHA_ROMAN'\r\n }\r\n });\r\n } else {\r\n requests.push({\r\n createParagraphBullets: {\r\n objectId: args.objectId,\r\n bulletPreset: `BULLET_${args.bulletStyle}_CIRCLE_SQUARE`\r\n }\r\n });\r\n }\r\n }\r\n\r\n if (requests.length === 0) {\r\n return errorResponse(\"No formatting options specified\");\r\n }\r\n\r\n await slidesService.presentations.batchUpdate({\r\n presentationId: args.presentationId,\r\n requestBody: { requests }\r\n });\r\n\r\n return {\r\n content: [{ type: \"text\", text: `Applied paragraph formatting to object ${args.objectId}` }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"styleGoogleSlidesShape\": {\r\n const validation = StyleGoogleSlidesShapeSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const slidesService = google.slides({ version: 'v1', auth: authClient });\r\n const shapeProperties: any = {};\r\n const fields: string[] = [];\r\n\r\n if (args.backgroundColor) {\r\n shapeProperties.shapeBackgroundFill = {\r\n solidFill: {\r\n color: {\r\n rgbColor: {\r\n red: args.backgroundColor.red || 0,\r\n green: args.backgroundColor.green || 0,\r\n blue: args.backgroundColor.blue || 0\r\n }\r\n },\r\n alpha: args.backgroundColor.alpha || 1\r\n }\r\n };\r\n fields.push('shapeBackgroundFill');\r\n }\r\n\r\n const outline: any = {};\r\n let hasOutlineChanges = false;\r\n\r\n if (args.outlineColor) {\r\n outline.outlineFill = {\r\n solidFill: {\r\n color: {\r\n rgbColor: {\r\n red: args.outlineColor.red || 0,\r\n green: args.outlineColor.green || 0,\r\n blue: args.outlineColor.blue || 0\r\n }\r\n }\r\n }\r\n };\r\n hasOutlineChanges = true;\r\n }\r\n\r\n if (args.outlineWeight !== undefined) {\r\n outline.weight = {\r\n magnitude: args.outlineWeight,\r\n unit: 'PT'\r\n };\r\n hasOutlineChanges = true;\r\n }\r\n\r\n if (args.outlineDashStyle !== undefined) {\r\n outline.dashStyle = args.outlineDashStyle;\r\n hasOutlineChanges = true;\r\n }\r\n\r\n if (hasOutlineChanges) {\r\n shapeProperties.outline = outline;\r\n fields.push('outline');\r\n }\r\n\r\n if (fields.length === 0) {\r\n return errorResponse(\"No styling options specified\");\r\n }\r\n\r\n await slidesService.presentations.batchUpdate({\r\n presentationId: args.presentationId,\r\n requestBody: {\r\n requests: [{\r\n updateShapeProperties: {\r\n objectId: args.objectId,\r\n shapeProperties,\r\n fields: fields.join(',')\r\n }\r\n }]\r\n }\r\n });\r\n\r\n return {\r\n content: [{ type: \"text\", text: `Applied styling to shape ${args.objectId}` }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"setGoogleSlidesBackground\": {\r\n const validation = SetGoogleSlidesBackgroundSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const slidesService = google.slides({ version: 'v1', auth: authClient });\r\n const requests = args.pageObjectIds.map(pageObjectId => ({\r\n updatePageProperties: {\r\n objectId: pageObjectId,\r\n pageProperties: {\r\n pageBackgroundFill: {\r\n solidFill: {\r\n color: {\r\n rgbColor: {\r\n red: args.backgroundColor.red || 0,\r\n green: args.backgroundColor.green || 0,\r\n blue: args.backgroundColor.blue || 0\r\n }\r\n },\r\n alpha: args.backgroundColor.alpha || 1\r\n }\r\n }\r\n },\r\n fields: 'pageBackgroundFill'\r\n }\r\n }));\r\n\r\n await slidesService.presentations.batchUpdate({\r\n presentationId: args.presentationId,\r\n requestBody: { requests }\r\n });\r\n\r\n return {\r\n content: [{ type: \"text\", text: `Set background color for ${args.pageObjectIds.length} slide(s)` }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"createGoogleSlidesTextBox\": {\r\n const validation = CreateGoogleSlidesTextBoxSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const slidesService = google.slides({ version: 'v1', auth: authClient });\r\n const elementId = `textBox_${uuidv4().substring(0, 8)}`;\r\n\r\n const requests: any[] = [\r\n {\r\n createShape: {\r\n objectId: elementId,\r\n shapeType: 'TEXT_BOX',\r\n elementProperties: {\r\n pageObjectId: args.pageObjectId,\r\n size: {\r\n width: { magnitude: args.width, unit: 'EMU' },\r\n height: { magnitude: args.height, unit: 'EMU' }\r\n },\r\n transform: {\r\n scaleX: 1,\r\n scaleY: 1,\r\n translateX: args.x,\r\n translateY: args.y,\r\n unit: 'EMU'\r\n }\r\n }\r\n }\r\n },\r\n {\r\n insertText: {\r\n objectId: elementId,\r\n text: args.text,\r\n insertionIndex: 0\r\n }\r\n }\r\n ];\r\n\r\n // Apply optional formatting\r\n if (args.fontSize || args.bold || args.italic) {\r\n const textStyle: any = {};\r\n const fields: string[] = [];\r\n\r\n if (args.fontSize) {\r\n textStyle.fontSize = {\r\n magnitude: args.fontSize,\r\n unit: 'PT'\r\n };\r\n fields.push('fontSize');\r\n }\r\n\r\n if (args.bold !== undefined) {\r\n textStyle.bold = args.bold;\r\n fields.push('bold');\r\n }\r\n\r\n if (args.italic !== undefined) {\r\n textStyle.italic = args.italic;\r\n fields.push('italic');\r\n }\r\n\r\n if (fields.length > 0) {\r\n requests.push({\r\n updateTextStyle: {\r\n objectId: elementId,\r\n style: textStyle,\r\n fields: fields.join(','),\r\n textRange: { type: 'ALL' }\r\n }\r\n });\r\n }\r\n }\r\n\r\n await slidesService.presentations.batchUpdate({\r\n presentationId: args.presentationId,\r\n requestBody: { requests }\r\n });\r\n\r\n return {\r\n content: [{ type: \"text\", text: `Created text box with ID: ${elementId}` }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"createGoogleSlidesShape\": {\r\n const validation = CreateGoogleSlidesShapeSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const slidesService = google.slides({ version: 'v1', auth: authClient });\r\n const elementId = `shape_${uuidv4().substring(0, 8)}`;\r\n\r\n const createRequest: any = {\r\n createShape: {\r\n objectId: elementId,\r\n shapeType: args.shapeType,\r\n elementProperties: {\r\n pageObjectId: args.pageObjectId,\r\n size: {\r\n width: { magnitude: args.width, unit: 'EMU' },\r\n height: { magnitude: args.height, unit: 'EMU' }\r\n },\r\n transform: {\r\n scaleX: 1,\r\n scaleY: 1,\r\n translateX: args.x,\r\n translateY: args.y,\r\n unit: 'EMU'\r\n }\r\n }\r\n }\r\n };\r\n\r\n const requests = [createRequest];\r\n\r\n // Apply background color if specified\r\n if (args.backgroundColor) {\r\n requests.push({\r\n updateShapeProperties: {\r\n objectId: elementId,\r\n shapeProperties: {\r\n shapeBackgroundFill: {\r\n solidFill: {\r\n color: {\r\n rgbColor: {\r\n red: args.backgroundColor.red || 0,\r\n green: args.backgroundColor.green || 0,\r\n blue: args.backgroundColor.blue || 0\r\n }\r\n },\r\n alpha: args.backgroundColor.alpha || 1\r\n }\r\n }\r\n },\r\n fields: 'shapeBackgroundFill'\r\n }\r\n });\r\n }\r\n\r\n await slidesService.presentations.batchUpdate({\r\n presentationId: args.presentationId,\r\n requestBody: { requests }\r\n });\r\n\r\n return {\r\n content: [{ type: \"text\", text: `Created ${args.shapeType} shape with ID: ${elementId}` }],\r\n isError: false\r\n };\r\n }\r\n\r\n default:\r\n return errorResponse(\"Tool not found\");\r\n }\r\n } catch (error) {\r\n log('Error in tool request handler', { error: (error as Error).message });\r\n return errorResponse((error as Error).message);\r\n }\r\n});\r\n\r\n// -----------------------------------------------------------------------------\r\n// CLI FUNCTIONS\r\n// -----------------------------------------------------------------------------\r\n\r\nfunction showHelp(): void {\r\n console.log(`\r\nGoogle Drive MCP Server v${VERSION}\r\n\r\nUsage:\r\n npx @yourusername/google-drive-mcp [command]\r\n\r\nCommands:\r\n auth Run the authentication flow\r\n start Start the MCP server (default)\r\n version Show version information\r\n help Show this help message\r\n\r\nExamples:\r\n npx @yourusername/google-drive-mcp auth\r\n npx @yourusername/google-drive-mcp start\r\n npx @yourusername/google-drive-mcp version\r\n npx @yourusername/google-drive-mcp\r\n\r\nEnvironment Variables:\r\n GOOGLE_DRIVE_OAUTH_CREDENTIALS Path to OAuth credentials file\r\n GOOGLE_DRIVE_MCP_TOKEN_PATH Path to store authentication tokens\r\n`);\r\n}\r\n\r\nfunction showVersion(): void {\r\n console.log(`Google Drive MCP Server v${VERSION}`);\r\n}\r\n\r\nasync function runAuthServer(): Promise<void> {\r\n try {\r\n // Initialize OAuth client\r\n const oauth2Client = await initializeOAuth2Client();\r\n\r\n // Create and start the auth server\r\n const authServerInstance = new AuthServer(oauth2Client);\r\n\r\n // Start with browser opening (true by default)\r\n const success = await authServerInstance.start(true);\r\n\r\n if (!success && !authServerInstance.authCompletedSuccessfully) {\r\n // Failed to start and tokens weren't already valid\r\n console.error(\r\n \"Authentication failed. Could not start server or validate existing tokens. Check port availability (3000-3004) and try again.\"\r\n );\r\n process.exit(1);\r\n } else if (authServerInstance.authCompletedSuccessfully) {\r\n // Auth was successful (either existing tokens were valid or flow completed just now)\r\n console.log(\"Authentication successful.\");\r\n process.exit(0); // Exit cleanly if auth is already done\r\n }\r\n\r\n // If we reach here, the server started and is waiting for the browser callback\r\n console.log(\r\n \"Authentication server started. Please complete the authentication in your browser...\"\r\n );\r\n\r\n // Wait for completion\r\n const intervalId = setInterval(async () => {\r\n if (authServerInstance.authCompletedSuccessfully) {\r\n clearInterval(intervalId);\r\n await authServerInstance.stop();\r\n console.log(\"Authentication completed successfully!\");\r\n process.exit(0);\r\n }\r\n }, 1000);\r\n } catch (error) {\r\n console.error(\"Authentication failed:\", error);\r\n process.exit(1);\r\n }\r\n}\r\n\r\n// -----------------------------------------------------------------------------\r\n// MAIN EXECUTION\r\n// -----------------------------------------------------------------------------\r\n\r\nfunction parseCliArgs(): { command: string | undefined } {\r\n const args = process.argv.slice(2);\r\n let command: string | undefined;\r\n\r\n for (let i = 0; i < args.length; i++) {\r\n const arg = args[i];\r\n \r\n // Handle special version/help flags as commands\r\n if (arg === '--version' || arg === '-v' || arg === '--help' || arg === '-h') {\r\n command = arg;\r\n continue;\r\n }\r\n \r\n // Check for command (first non-option argument)\r\n if (!command && !arg.startsWith('--')) {\r\n command = arg;\r\n continue;\r\n }\r\n }\r\n\r\n return { command };\r\n}\r\n\r\nasync function main() {\r\n const { command } = parseCliArgs();\r\n\r\n switch (command) {\r\n case \"auth\":\r\n await runAuthServer();\r\n break;\r\n case \"start\":\r\n case undefined:\r\n try {\r\n // Start the MCP server\r\n console.error(\"Starting Google Drive MCP server...\");\r\n const transport = new StdioServerTransport();\r\n await server.connect(transport);\r\n log('Server started successfully');\r\n \r\n // Set up graceful shutdown\r\n process.on(\"SIGINT\", async () => {\r\n await server.close();\r\n process.exit(0);\r\n });\r\n process.on(\"SIGTERM\", async () => {\r\n await server.close();\r\n process.exit(0);\r\n });\r\n } catch (error) {\r\n console.error('Failed to start server:', error);\r\n process.exit(1);\r\n }\r\n break;\r\n case \"version\":\r\n case \"--version\":\r\n case \"-v\":\r\n showVersion();\r\n break;\r\n case \"help\":\r\n case \"--help\":\r\n case \"-h\":\r\n showHelp();\r\n break;\r\n default:\r\n console.error(`Unknown command: ${command}`);\r\n showHelp();\r\n process.exit(1);\r\n }\r\n}\r\n\r\n// Export server and main for testing or potential programmatic use\r\nexport { main, server };\r\n\r\n// Run the CLI\r\nmain().catch((error) => {\r\n console.error(\"Fatal error:\", error);\r\n process.exit(1);\r\n});", "import { OAuth2Client } from 'google-auth-library';\r\nimport * as fs from 'fs/promises';\r\nimport { getKeysFilePath, generateCredentialsErrorMessage, OAuthCredentials } from './utils.js';\r\n\r\nasync function loadCredentialsFromFile(): Promise<OAuthCredentials> {\r\n const keysContent = await fs.readFile(getKeysFilePath(), \"utf-8\");\r\n const keys = JSON.parse(keysContent);\r\n\r\n if (keys.installed) {\r\n // Standard OAuth credentials file format\r\n const { client_id, client_secret, redirect_uris } = keys.installed;\r\n return { client_id, client_secret, redirect_uris };\r\n } else if (keys.web) {\r\n // Web application credentials format\r\n const { client_id, client_secret, redirect_uris } = keys.web;\r\n return { client_id, client_secret, redirect_uris };\r\n } else if (keys.client_id) {\r\n // Direct format (simplified)\r\n return {\r\n client_id: keys.client_id,\r\n client_secret: keys.client_secret,\r\n redirect_uris: keys.redirect_uris || ['http://localhost:3000/oauth2callback']\r\n };\r\n } else {\r\n throw new Error('Invalid credentials file format. Expected either \"installed\", \"web\" object or direct client_id field.');\r\n }\r\n}\r\n\r\nasync function loadCredentialsWithFallback(): Promise<OAuthCredentials> {\r\n try {\r\n return await loadCredentialsFromFile();\r\n } catch (fileError) {\r\n // Check for legacy client_secret.json\r\n const legacyPath = process.env.GOOGLE_CLIENT_SECRET_PATH || 'client_secret.json';\r\n try {\r\n const legacyContent = await fs.readFile(legacyPath, 'utf-8');\r\n const legacyKeys = JSON.parse(legacyContent);\r\n console.error('Warning: Using legacy client_secret.json. Please migrate to gcp-oauth.keys.json');\r\n \r\n if (legacyKeys.installed) {\r\n return legacyKeys.installed;\r\n } else if (legacyKeys.web) {\r\n return legacyKeys.web;\r\n } else {\r\n throw new Error('Invalid legacy credentials format');\r\n }\r\n } catch (legacyError) {\r\n // Generate helpful error message\r\n const errorMessage = generateCredentialsErrorMessage();\r\n throw new Error(`${errorMessage}\\n\\nOriginal error: ${fileError instanceof Error ? fileError.message : fileError}`);\r\n }\r\n }\r\n}\r\n\r\nexport async function initializeOAuth2Client(): Promise<OAuth2Client> {\r\n try {\r\n const credentials = await loadCredentialsWithFallback();\r\n \r\n // Use the first redirect URI as the default for the base client\r\n return new OAuth2Client({\r\n clientId: credentials.client_id,\r\n clientSecret: credentials.client_secret || undefined,\r\n redirectUri: credentials.redirect_uris?.[0] || 'http://localhost:3000/oauth2callback',\r\n });\r\n } catch (error) {\r\n throw new Error(`Error loading OAuth keys: ${error instanceof Error ? error.message : error}`);\r\n }\r\n}\r\n\r\nexport async function loadCredentials(): Promise<{ client_id: string; client_secret?: string }> {\r\n try {\r\n const credentials = await loadCredentialsWithFallback();\r\n \r\n if (!credentials.client_id) {\r\n throw new Error('Client ID missing in credentials.');\r\n }\r\n return {\r\n client_id: credentials.client_id,\r\n client_secret: credentials.client_secret\r\n };\r\n } catch (error) {\r\n throw new Error(`Error loading credentials: ${error instanceof Error ? error.message : error}`);\r\n }\r\n}", "import * as path from 'path';\r\nimport * as os from 'os';\r\nimport { fileURLToPath } from 'url';\r\n\r\n// Helper to get the project root directory reliably\r\nfunction getProjectRoot(): string {\r\n const __dirname = path.dirname(fileURLToPath(import.meta.url));\r\n // In build output (e.g., dist/auth/utils.js), __dirname is .../dist/auth\r\n // Go up TWO levels to get the project root\r\n const projectRoot = path.join(__dirname, \"..\", \"..\");\r\n return path.resolve(projectRoot);\r\n}\r\n\r\n// Returns the absolute path for the saved token file.\r\n// Uses XDG Base Directory spec with fallback to home directory\r\nexport function getSecureTokenPath(): string {\r\n // Check for custom token path environment variable first\r\n const customTokenPath = process.env.GOOGLE_DRIVE_MCP_TOKEN_PATH;\r\n if (customTokenPath) {\r\n return path.resolve(customTokenPath);\r\n }\r\n\r\n // Use XDG Base Directory spec or fallback to ~/.config\r\n const configHome = process.env.XDG_CONFIG_HOME || \r\n path.join(os.homedir(), '.config');\r\n \r\n const tokenDir = path.join(configHome, 'google-drive-mcp');\r\n return path.join(tokenDir, 'tokens.json');\r\n}\r\n\r\n// Returns the legacy token path for backward compatibility\r\nexport function getLegacyTokenPath(): string {\r\n const projectRoot = getProjectRoot();\r\n return path.join(projectRoot, \".gcp-saved-tokens.json\");\r\n}\r\n\r\n// Additional legacy paths to check\r\nexport function getAdditionalLegacyPaths(): string[] {\r\n return [\r\n process.env.GOOGLE_TOKEN_PATH,\r\n path.join(process.cwd(), 'google-tokens.json'),\r\n path.join(process.cwd(), '.gcp-saved-tokens.json')\r\n ].filter(Boolean) as string[];\r\n}\r\n\r\n// Returns the absolute path for the GCP OAuth keys file with priority:\r\n// 1. Environment variable GOOGLE_DRIVE_OAUTH_CREDENTIALS (highest priority)\r\n// 2. Default file path (lowest priority)\r\nexport function getKeysFilePath(): string {\r\n // Priority 1: Environment variable\r\n const envCredentialsPath = process.env.GOOGLE_DRIVE_OAUTH_CREDENTIALS;\r\n if (envCredentialsPath) {\r\n return path.resolve(envCredentialsPath);\r\n }\r\n \r\n // Priority 2: Default file path\r\n const projectRoot = getProjectRoot();\r\n const keysPath = path.join(projectRoot, \"gcp-oauth.keys.json\");\r\n return keysPath;\r\n}\r\n\r\n// Interface for OAuth credentials\r\nexport interface OAuthCredentials {\r\n client_id: string;\r\n client_secret?: string;\r\n redirect_uris?: string[];\r\n}\r\n\r\n// Generate helpful error message for missing credentials\r\nexport function generateCredentialsErrorMessage(): string {\r\n return `\r\nOAuth credentials not found. Please provide credentials using one of these methods:\r\n\r\n1. Environment variable:\r\n Set GOOGLE_DRIVE_OAUTH_CREDENTIALS to the path of your credentials file:\r\n export GOOGLE_DRIVE_OAUTH_CREDENTIALS=\"/path/to/gcp-oauth.keys.json\"\r\n\r\n2. Default file path:\r\n Place your gcp-oauth.keys.json file in the package root directory.\r\n\r\nToken storage:\r\n- Tokens are saved to: ${getSecureTokenPath()}\r\n- To use a custom token location, set GOOGLE_DRIVE_MCP_TOKEN_PATH environment variable\r\n\r\nTo get OAuth credentials:\r\n1. Go to the Google Cloud Console (https://console.cloud.google.com/)\r\n2. Create or select a project\r\n3. Enable the Google Drive, Docs, Sheets, and Slides APIs\r\n4. Create OAuth 2.0 credentials (Desktop app type)\r\n5. Download the credentials file as gcp-oauth.keys.json\r\n`.trim();\r\n}", "import express from 'express';\r\nimport { OAuth2Client } from 'google-auth-library';\r\nimport { TokenManager } from './tokenManager.js';\r\nimport http from 'http';\r\nimport open from 'open';\r\nimport { loadCredentials } from './client.js';\r\n\r\n// OAuth scopes for Google Drive, Docs, Sheets, and Slides\r\nconst SCOPES = [\r\n 'https://www.googleapis.com/auth/drive',\r\n 'https://www.googleapis.com/auth/drive.file',\r\n 'https://www.googleapis.com/auth/drive.readonly',\r\n 'https://www.googleapis.com/auth/documents',\r\n 'https://www.googleapis.com/auth/spreadsheets',\r\n 'https://www.googleapis.com/auth/presentations'\r\n];\r\n\r\nexport class AuthServer {\r\n private baseOAuth2Client: OAuth2Client; // Used by TokenManager for validation/refresh\r\n private flowOAuth2Client: OAuth2Client | null = null; // Used specifically for the auth code flow\r\n private app: express.Express;\r\n private server: http.Server | null = null;\r\n private tokenManager: TokenManager;\r\n private portRange: { start: number; end: number };\r\n public authCompletedSuccessfully = false; // Flag for standalone script\r\n\r\n constructor(oauth2Client: OAuth2Client) {\r\n this.baseOAuth2Client = oauth2Client;\r\n this.tokenManager = new TokenManager(oauth2Client);\r\n this.app = express();\r\n this.portRange = { start: 3000, end: 3004 };\r\n this.setupRoutes();\r\n }\r\n\r\n private setupRoutes(): void {\r\n this.app.get('/', (req, res) => {\r\n // Generate the URL using the active flow client if available, else base\r\n const clientForUrl = this.flowOAuth2Client || this.baseOAuth2Client;\r\n const authUrl = clientForUrl.generateAuthUrl({\r\n access_type: 'offline',\r\n scope: SCOPES,\r\n prompt: 'consent'\r\n });\r\n res.send(`<h1>Google Drive Authentication</h1><a href=\"${authUrl}\">Authenticate with Google</a>`);\r\n });\r\n\r\n this.app.get('/oauth2callback', async (req, res) => {\r\n const code = req.query.code as string;\r\n if (!code) {\r\n res.status(400).send('Authorization code missing');\r\n return;\r\n }\r\n // IMPORTANT: Use the flowOAuth2Client to exchange the code\r\n if (!this.flowOAuth2Client) {\r\n res.status(500).send('Authentication flow not properly initiated.');\r\n return;\r\n }\r\n try {\r\n const { tokens } = await this.flowOAuth2Client.getToken(code);\r\n // Save tokens using the TokenManager (which uses the base client)\r\n await this.tokenManager.saveTokens(tokens);\r\n this.authCompletedSuccessfully = true;\r\n\r\n // Get the path where tokens were saved\r\n const tokenPath = this.tokenManager.getTokenPath();\r\n\r\n // Send a more informative HTML response including the path\r\n res.send(`\r\n <!DOCTYPE html>\r\n <html lang=\"en\">\r\n <head>\r\n <meta charset=\"UTF-8\">\r\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n <title>Authentication Successful</title>\r\n <style>\r\n body { font-family: sans-serif; display: flex; justify-content: center; align-items: center; height: 100vh; background-color: #f4f4f4; margin: 0; }\r\n .container { text-align: center; padding: 2em; background-color: #fff; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }\r\n h1 { color: #4CAF50; }\r\n p { color: #333; margin-bottom: 0.5em; }\r\n code { background-color: #eee; padding: 0.2em 0.4em; border-radius: 3px; font-size: 0.9em; }\r\n </style>\r\n </head>\r\n <body>\r\n <div class=\"container\">\r\n <h1>Authentication Successful!</h1>\r\n <p>Your authentication tokens have been saved successfully to:</p>\r\n <p><code>${tokenPath}</code></p>\r\n <p>You can now close this browser window.</p>\r\n </div>\r\n </body>\r\n </html>\r\n `);\r\n } catch (error: unknown) {\r\n this.authCompletedSuccessfully = false;\r\n const message = error instanceof Error ? error.message : 'Unknown error';\r\n // Send an HTML error response\r\n res.status(500).send(`\r\n <!DOCTYPE html>\r\n <html lang=\"en\">\r\n <head>\r\n <meta charset=\"UTF-8\">\r\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n <title>Authentication Failed</title>\r\n <style>\r\n body { font-family: sans-serif; display: flex; justify-content: center; align-items: center; height: 100vh; background-color: #f4f4f4; margin: 0; }\r\n .container { text-align: center; padding: 2em; background-color: #fff; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }\r\n h1 { color: #F44336; }\r\n p { color: #333; }\r\n </style>\r\n </head>\r\n <body>\r\n <div class=\"container\">\r\n <h1>Authentication Failed</h1>\r\n <p>An error occurred during authentication:</p>\r\n <p><code>${message}</code></p>\r\n <p>Please try again or check the server logs.</p>\r\n </div>\r\n </body>\r\n </html>\r\n `);\r\n }\r\n });\r\n }\r\n\r\n async start(openBrowser = true): Promise<boolean> {\r\n if (await this.tokenManager.validateTokens()) {\r\n this.authCompletedSuccessfully = true;\r\n return true;\r\n }\r\n \r\n // Try to start the server and get the port\r\n const port = await this.startServerOnAvailablePort();\r\n if (port === null) {\r\n this.authCompletedSuccessfully = false;\r\n return false;\r\n }\r\n\r\n // Successfully started server on `port`. Now create the flow-specific OAuth client.\r\n try {\r\n const { client_id, client_secret } = await loadCredentials();\r\n this.flowOAuth2Client = new OAuth2Client(\r\n client_id,\r\n client_secret || undefined,\r\n `http://localhost:${port}/oauth2callback`\r\n );\r\n } catch (error) {\r\n // Could not load credentials, cannot proceed with auth flow\r\n console.error('Failed to load credentials for auth flow:', error);\r\n this.authCompletedSuccessfully = false;\r\n await this.stop(); // Stop the server we just started\r\n return false;\r\n }\r\n\r\n if (openBrowser) {\r\n // Generate Auth URL using the newly created flow client\r\n const authorizeUrl = this.flowOAuth2Client.generateAuthUrl({\r\n access_type: 'offline',\r\n scope: SCOPES,\r\n prompt: 'consent'\r\n });\r\n \r\n console.error('\\n\uD83D\uDD10 AUTHENTICATION REQUIRED');\r\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');\r\n console.error('\\nOpening your browser to authenticate...');\r\n console.error(`If the browser doesn't open, visit:\\n${authorizeUrl}\\n`);\r\n \r\n await open(authorizeUrl);\r\n }\r\n\r\n return true; // Auth flow initiated\r\n }\r\n\r\n private async startServerOnAvailablePort(): Promise<number | null> {\r\n for (let port = this.portRange.start; port <= this.portRange.end; port++) {\r\n try {\r\n await new Promise<void>((resolve, reject) => {\r\n // Create a temporary server instance to test the port\r\n const testServer = this.app.listen(port, () => {\r\n this.server = testServer; // Assign to class property *only* if successful\r\n console.error(`Authentication server listening on http://localhost:${port}`);\r\n resolve();\r\n });\r\n testServer.on('error', (err: NodeJS.ErrnoException) => {\r\n if (err.code === 'EADDRINUSE') {\r\n // Port is in use, close the test server and reject\r\n testServer.close(() => reject(err)); \r\n } else {\r\n // Other error, reject\r\n reject(err);\r\n }\r\n });\r\n });\r\n return port; // Port successfully bound\r\n } catch (error: unknown) {\r\n // Check if it's EADDRINUSE, otherwise rethrow or handle\r\n if (!(error instanceof Error && 'code' in error && (error as any).code === 'EADDRINUSE')) {\r\n // An unexpected error occurred during server start\r\n console.error('Failed to start auth server:', error);\r\n return null;\r\n }\r\n // EADDRINUSE occurred, loop continues\r\n }\r\n }\r\n console.error('No available ports for authentication server (tried ports', this.portRange.start, '-', this.portRange.end, ')');\r\n return null; // No port found\r\n }\r\n\r\n public getRunningPort(): number | null {\r\n if (this.server) {\r\n const address = this.server.address();\r\n if (typeof address === 'object' && address !== null) {\r\n return address.port;\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n async stop(): Promise<void> {\r\n return new Promise((resolve, reject) => {\r\n if (this.server) {\r\n this.server.close((err) => {\r\n if (err) {\r\n reject(err);\r\n } else {\r\n this.server = null;\r\n resolve();\r\n }\r\n });\r\n } else {\r\n resolve();\r\n }\r\n });\r\n }\r\n}", "import { OAuth2Client, Credentials } from 'google-auth-library';\r\nimport * as fs from 'fs/promises';\r\nimport * as path from 'path';\r\nimport { getSecureTokenPath, getLegacyTokenPath, getAdditionalLegacyPaths } from './utils.js';\r\nimport { GaxiosError } from 'gaxios';\r\n\r\nexport class TokenManager {\r\n private oauth2Client: OAuth2Client;\r\n private tokenPath: string;\r\n\r\n constructor(oauth2Client: OAuth2Client) {\r\n this.oauth2Client = oauth2Client;\r\n this.tokenPath = getSecureTokenPath();\r\n this.setupTokenRefresh();\r\n }\r\n\r\n // Method to expose the token path\r\n public getTokenPath(): string {\r\n return this.tokenPath;\r\n }\r\n\r\n private async ensureTokenDirectoryExists(): Promise<void> {\r\n try {\r\n const dir = path.dirname(this.tokenPath);\r\n await fs.mkdir(dir, { recursive: true });\r\n } catch (error: unknown) {\r\n // Ignore errors if directory already exists, re-throw others\r\n if (error instanceof Error && 'code' in error && (error as any).code !== 'EEXIST') {\r\n console.error('Failed to create token directory:', error);\r\n throw error;\r\n }\r\n }\r\n }\r\n\r\n private setupTokenRefresh(): void {\r\n this.oauth2Client.on(\"tokens\", async (newTokens) => {\r\n try {\r\n await this.ensureTokenDirectoryExists();\r\n const currentTokens = JSON.parse(await fs.readFile(this.tokenPath, \"utf-8\"));\r\n const updatedTokens = {\r\n ...currentTokens,\r\n ...newTokens,\r\n refresh_token: newTokens.refresh_token || currentTokens.refresh_token,\r\n };\r\n await fs.writeFile(this.tokenPath, JSON.stringify(updatedTokens, null, 2), {\r\n mode: 0o600,\r\n });\r\n console.error(\"Tokens updated and saved\");\r\n } catch (error: unknown) {\r\n // Handle case where currentTokens might not exist yet\r\n if (error instanceof Error && 'code' in error && (error as any).code === 'ENOENT') { \r\n try {\r\n await fs.writeFile(this.tokenPath, JSON.stringify(newTokens, null, 2), { mode: 0o600 });\r\n console.error(\"New tokens saved\");\r\n } catch (writeError) {\r\n console.error(\"Error saving initial tokens:\", writeError);\r\n }\r\n } else {\r\n console.error(\"Error saving updated tokens:\", error);\r\n }\r\n }\r\n });\r\n }\r\n\r\n private async migrateLegacyTokens(): Promise<boolean> {\r\n // Check all possible legacy locations\r\n const legacyPaths = [getLegacyTokenPath(), ...getAdditionalLegacyPaths()];\r\n \r\n for (const legacyPath of legacyPaths) {\r\n try {\r\n // Check if legacy tokens exist\r\n if (!(await fs.access(legacyPath).then(() => true).catch(() => false))) {\r\n continue; // Try next location\r\n }\r\n\r\n // Read legacy tokens\r\n const legacyTokens = JSON.parse(await fs.readFile(legacyPath, \"utf-8\"));\r\n \r\n if (!legacyTokens || typeof legacyTokens !== \"object\") {\r\n console.error(\"Invalid legacy token format at\", legacyPath, \", skipping\");\r\n continue;\r\n }\r\n\r\n // Ensure new token directory exists\r\n await this.ensureTokenDirectoryExists();\r\n \r\n // Copy to new location\r\n await fs.writeFile(this.tokenPath, JSON.stringify(legacyTokens, null, 2), {\r\n mode: 0o600,\r\n });\r\n \r\n console.error(\"Migrated tokens from legacy location:\", legacyPath, \"to:\", this.tokenPath);\r\n \r\n // Optionally remove legacy file after successful migration\r\n try {\r\n await fs.unlink(legacyPath);\r\n console.error(\"Removed legacy token file\");\r\n } catch (unlinkErr) {\r\n console.error(\"Warning: Could not remove legacy token file:\", unlinkErr);\r\n }\r\n \r\n return true;\r\n } catch (error) {\r\n console.error(\"Error migrating legacy tokens from\", legacyPath, \":\", error);\r\n // Continue to next location\r\n }\r\n }\r\n \r\n return false; // No legacy tokens found or migrated\r\n }\r\n\r\n async loadSavedTokens(): Promise<boolean> {\r\n try {\r\n await this.ensureTokenDirectoryExists();\r\n \r\n // Check if current token file exists\r\n const tokenExists = await fs.access(this.tokenPath).then(() => true).catch(() => false);\r\n \r\n // If no current tokens, try to migrate from legacy location\r\n if (!tokenExists) {\r\n const migrated = await this.migrateLegacyTokens();\r\n if (!migrated) {\r\n console.error(\"No token file found at:\", this.tokenPath);\r\n return false;\r\n }\r\n }\r\n\r\n const tokens = JSON.parse(await fs.readFile(this.tokenPath, \"utf-8\"));\r\n\r\n if (!tokens || typeof tokens !== \"object\") {\r\n console.error(\"Invalid token format in file:\", this.tokenPath);\r\n return false;\r\n }\r\n\r\n this.oauth2Client.setCredentials(tokens);\r\n console.error('Tokens loaded and set on OAuth2Client:', {\r\n hasAccessToken: !!tokens.access_token,\r\n hasRefreshToken: !!tokens.refresh_token,\r\n tokenLength: tokens.access_token?.length,\r\n expiryDate: tokens.expiry_date,\r\n scope: tokens.scope\r\n });\r\n console.error('OAuth2Client after setCredentials:', {\r\n hasCredentials: !!this.oauth2Client.credentials,\r\n credentialsAccessToken: !!this.oauth2Client.credentials?.access_token\r\n });\r\n return true;\r\n } catch (error: unknown) {\r\n console.error(\"Error loading tokens:\", error);\r\n // Attempt to delete potentially corrupted token file\r\n if (error instanceof Error && 'code' in error && (error as any).code !== 'ENOENT') { \r\n try { \r\n await fs.unlink(this.tokenPath); \r\n console.error(\"Removed potentially corrupted token file\") \r\n } catch (unlinkErr) { /* ignore */ } \r\n }\r\n return false;\r\n }\r\n }\r\n\r\n async refreshTokensIfNeeded(): Promise<boolean> {\r\n const expiryDate = this.oauth2Client.credentials.expiry_date;\r\n const isExpired = expiryDate\r\n ? Date.now() >= expiryDate - 5 * 60 * 1000 // 5 minute buffer\r\n : !this.oauth2Client.credentials.access_token; // No token means we need one\r\n\r\n if (isExpired && this.oauth2Client.credentials.refresh_token) {\r\n console.error(\"Auth token expired or nearing expiry, refreshing...\");\r\n try {\r\n const response = await this.oauth2Client.refreshAccessToken();\r\n const newTokens = response.credentials;\r\n\r\n if (!newTokens.access_token) {\r\n throw new Error(\"Received invalid tokens during refresh\");\r\n }\r\n // The 'tokens' event listener should handle saving\r\n this.oauth2Client.setCredentials(newTokens);\r\n console.error(\"Token refreshed successfully\");\r\n return true;\r\n } catch (refreshError) {\r\n if (refreshError instanceof GaxiosError && refreshError.response?.data?.error === 'invalid_grant') {\r\n console.error(\"Error refreshing auth token: Invalid grant. Token likely expired or revoked. Please re-authenticate.\");\r\n // Optionally clear the potentially invalid tokens here\r\n await this.clearTokens(); \r\n return false; // Indicate failure due to invalid grant\r\n } else {\r\n // Handle other refresh errors\r\n console.error(\"Error refreshing auth token:\", refreshError);\r\n return false;\r\n }\r\n }\r\n } else if (!this.oauth2Client.credentials.access_token && !this.oauth2Client.credentials.refresh_token) {\r\n console.error(\"No access or refresh token available. Please re-authenticate.\");\r\n return false;\r\n } else {\r\n // Token is valid or no refresh token available\r\n return true;\r\n }\r\n }\r\n\r\n async validateTokens(): Promise<boolean> {\r\n if (!this.oauth2Client.credentials || !this.oauth2Client.credentials.access_token) {\r\n // Try loading first if no credentials set\r\n if (!(await this.loadSavedTokens())) {\r\n return false; // No saved tokens to load\r\n }\r\n // Check again after loading\r\n if (!this.oauth2Client.credentials || !this.oauth2Client.credentials.access_token) {\r\n return false; // Still no token after loading\r\n }\r\n }\r\n return this.refreshTokensIfNeeded();\r\n }\r\n\r\n async saveTokens(tokens: Credentials): Promise<void> {\r\n try {\r\n await this.ensureTokenDirectoryExists();\r\n await fs.writeFile(this.tokenPath, JSON.stringify(tokens, null, 2), { mode: 0o600 });\r\n this.oauth2Client.setCredentials(tokens);\r\n console.error(\"Tokens saved successfully to:\", this.tokenPath);\r\n } catch (error: unknown) {\r\n console.error(\"Error saving tokens:\", error);\r\n throw error;\r\n }\r\n }\r\n\r\n async clearTokens(): Promise<void> {\r\n try {\r\n this.oauth2Client.setCredentials({}); // Clear in memory\r\n await fs.unlink(this.tokenPath);\r\n console.error(\"Tokens cleared successfully\");\r\n } catch (error: unknown) {\r\n if (error instanceof Error && 'code' in error && (error as any).code === 'ENOENT') {\r\n // File already gone, which is fine\r\n console.error(\"Token file already deleted\");\r\n } else {\r\n console.error(\"Error clearing tokens:\", error);\r\n // Don't re-throw, clearing is best-effort\r\n }\r\n }\r\n }\r\n}", "// Main authentication module that re-exports and orchestrates the modular components\nimport { initializeOAuth2Client } from './auth/client.js';\nimport { AuthServer } from './auth/server.js';\nimport { TokenManager } from './auth/tokenManager.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<any> {\n console.error('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 console.error('Authentication successful - using existing tokens');\n console.error('OAuth2Client credentials:', {\n hasAccessToken: !!oauth2Client.credentials?.access_token,\n hasRefreshToken: !!oauth2Client.credentials?.refresh_token,\n expiryDate: oauth2Client.credentials?.expiry_date\n });\n return oauth2Client;\n }\n \n // No valid tokens, need to authenticate\n console.error('\\n\uD83D\uDD10 No valid authentication tokens found.');\n console.error('Starting authentication flow...\\n');\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/**\n * Manual authentication command\n * Used when running \"npm run auth\" or when the user needs to re-authenticate\n */\nexport async function runAuthCommand(): Promise<void> {\n try {\n console.error('Google Drive MCP - Manual Authentication');\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\\n');\n \n // Initialize OAuth client\n const oauth2Client = await initializeOAuth2Client();\n \n // Create and start the auth server\n const authServer = new AuthServer(oauth2Client);\n \n // Start with browser opening (true by default)\n const success = await authServer.start(true);\n \n if (!success && !authServer.authCompletedSuccessfully) {\n // Failed to start and tokens weren't already valid\n console.error(\n \"Authentication failed. Could not start server or validate existing tokens. Check port availability (3000-3004) and try again.\"\n );\n process.exit(1);\n } else if (authServer.authCompletedSuccessfully) {\n // Auth was successful (either existing tokens were valid or flow completed just now)\n console.error(\"\\n\u2705 Authentication successful!\");\n console.error(\"You can now use the Google Drive MCP server.\");\n process.exit(0); // Exit cleanly if auth is already done\n }\n \n // If we reach here, the server started and is waiting for the browser callback\n console.error(\n \"Authentication server started. Please complete the authentication in your browser...\"\n );\n \n // Wait for completion\n const intervalId = setInterval(async () => {\n if (authServer.authCompletedSuccessfully) {\n clearInterval(intervalId);\n await authServer.stop();\n console.error(\"\\n\u2705 Authentication completed successfully!\");\n console.error(\"You can now use the Google Drive MCP server.\");\n process.exit(0);\n }\n }, 1000);\n } catch (error) {\n console.error(\"\\n\u274C Authentication failed:\", error);\n process.exit(1);\n }\n}"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["#!/usr/bin/env node\r\n\r\nimport { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\r\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\r\nimport {\r\n CallToolRequestSchema,\r\n ListResourcesRequestSchema,\r\n ListToolsRequestSchema,\r\n ReadResourceRequestSchema,\r\n} from \"@modelcontextprotocol/sdk/types.js\";\r\nimport { google } from \"googleapis\";\r\nimport type { drive_v3 } from \"googleapis\";\r\nimport { v4 as uuidv4 } from 'uuid';\r\nimport { authenticate, runAuthCommand, AuthServer, initializeOAuth2Client } from './auth.js';\r\nimport { z } from 'zod';\r\nimport { fileURLToPath } from 'url';\r\nimport { readFileSync, createReadStream, existsSync, statSync } from 'fs';\r\nimport { join, dirname } from 'path';\r\n\r\n// Drive service - will be created with auth when needed\r\nlet drive: any = null;\r\n\r\n// Helper to ensure drive service has current auth\r\nfunction ensureDriveService() {\r\n if (!authClient) {\r\n throw new Error('Authentication required');\r\n }\r\n \r\n // Log detailed auth client info\r\n log('About to create drive service', {\r\n authClientType: authClient?.constructor?.name,\r\n hasCredentials: !!authClient.credentials,\r\n credentialsKeys: authClient.credentials ? Object.keys(authClient.credentials) : [],\r\n accessTokenLength: authClient.credentials?.access_token?.length,\r\n accessTokenPrefix: authClient.credentials?.access_token?.substring(0, 20),\r\n expiryDate: authClient.credentials?.expiry_date,\r\n isExpired: authClient.credentials?.expiry_date ? Date.now() > authClient.credentials.expiry_date : 'no expiry'\r\n });\r\n \r\n // Create drive service with auth parameter directly\r\n drive = google.drive({ version: 'v3', auth: authClient });\r\n \r\n log('Drive service created/updated', {\r\n hasAuth: !!authClient,\r\n hasCredentials: !!authClient.credentials,\r\n hasAccessToken: !!authClient.credentials?.access_token\r\n });\r\n \r\n // Test the auth by making a simple API call\r\n drive.about.get({ fields: 'user' })\r\n .then((response: any) => {\r\n log('Auth test successful, user:', response.data.user?.emailAddress);\r\n })\r\n .catch((error: any) => {\r\n log('Auth test failed:', error.message || error);\r\n if (error.response) {\r\n log('Auth test error details:', {\r\n status: error.response.status,\r\n statusText: error.response.statusText,\r\n headers: error.response.headers,\r\n data: error.response.data\r\n });\r\n }\r\n });\r\n}\r\n\r\n// -----------------------------------------------------------------------------\r\n// CONSTANTS & CONFIG\r\n// -----------------------------------------------------------------------------\r\nconst FOLDER_MIME_TYPE = 'application/vnd.google-apps.folder';\r\nconst TEXT_MIME_TYPES = {\r\n txt: 'text/plain',\r\n md: 'text/markdown'\r\n};\r\n\r\n// MIME types for binary file uploads (extension \u2192 MIME)\r\nconst BINARY_MIME_TYPES: Record<string, string> = {\r\n jpg: 'image/jpeg', jpeg: 'image/jpeg', png: 'image/png', gif: 'image/gif',\r\n webp: 'image/webp', svg: 'image/svg+xml', bmp: 'image/bmp', ico: 'image/x-icon',\r\n mp3: 'audio/mpeg', wav: 'audio/wav', ogg: 'audio/ogg', m4a: 'audio/mp4',\r\n aac: 'audio/aac', flac: 'audio/flac', opus: 'audio/opus',\r\n mp4: 'video/mp4', webm: 'video/webm', avi: 'video/x-msvideo', mov: 'video/quicktime',\r\n mkv: 'video/x-matroska', '3gp': 'video/3gpp',\r\n pdf: 'application/pdf', zip: 'application/zip', gz: 'application/gzip',\r\n tar: 'application/x-tar', json: 'application/json', xml: 'application/xml',\r\n csv: 'text/csv', html: 'text/html', css: 'text/css', js: 'application/javascript',\r\n doc: 'application/msword', docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\r\n xls: 'application/vnd.ms-excel', xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\r\n ppt: 'application/vnd.ms-powerpoint', pptx: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',\r\n};\r\n\r\n// Global auth client - will be initialized on first use\r\nlet authClient: any = null;\r\nlet authenticationPromise: Promise<any> | null = null;\r\n\r\n// Get package version\r\nconst __filename = fileURLToPath(import.meta.url);\r\nconst __dirname = dirname(__filename);\r\nconst packageJsonPath = join(__dirname, '..', 'package.json');\r\nconst packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\r\nconst VERSION = packageJson.version;\r\n\r\n// -----------------------------------------------------------------------------\r\n// LOGGING UTILITY\r\n// -----------------------------------------------------------------------------\r\nfunction log(message: string, data?: any) {\r\n const timestamp = new Date().toISOString();\r\n const logMessage = data\r\n ? `[${timestamp}] ${message}: ${JSON.stringify(data)}`\r\n : `[${timestamp}] ${message}`;\r\n console.error(logMessage);\r\n}\r\n\r\n// -----------------------------------------------------------------------------\r\n// HELPER FUNCTIONS\r\n// -----------------------------------------------------------------------------\r\nfunction getExtensionFromFilename(filename: string): string {\r\n return filename.split('.').pop()?.toLowerCase() || '';\r\n}\r\n\r\nfunction getMimeTypeFromFilename(filename: string): string {\r\n const ext = getExtensionFromFilename(filename);\r\n return TEXT_MIME_TYPES[ext as keyof typeof TEXT_MIME_TYPES] || 'text/plain';\r\n}\r\n\r\n\r\n\r\n/**\r\n * Resolve a slash-delimited path (e.g. \"/some/folder\") within Google Drive\r\n * into a folder ID. Creates folders if they don't exist.\r\n */\r\nasync function resolvePath(pathStr: string): Promise<string> {\r\n if (!pathStr || pathStr === '/') return 'root';\r\n\r\n // Note: This function is called after ensureAuthenticated, so drive should exist\r\n const parts = pathStr.replace(/^\\/+|\\/+$/g, '').split('/');\r\n let currentFolderId: string = 'root';\r\n\r\n for (const part of parts) {\r\n if (!part) continue;\r\n let response = await drive.files.list({\r\n q: `'${currentFolderId}' in parents and name = '${part}' and mimeType = '${FOLDER_MIME_TYPE}' and trashed = false`,\r\n fields: 'files(id)',\r\n spaces: 'drive',\r\n includeItemsFromAllDrives: true,\r\n supportsAllDrives: true\r\n });\r\n\r\n // If the folder segment doesn't exist, create it\r\n if (!response.data.files?.length) {\r\n const folderMetadata = {\r\n name: part,\r\n mimeType: FOLDER_MIME_TYPE,\r\n parents: [currentFolderId]\r\n };\r\n const folder = await drive.files.create({\r\n requestBody: folderMetadata,\r\n fields: 'id',\r\n supportsAllDrives: true\r\n });\r\n\r\n if (!folder.data.id) {\r\n throw new Error(`Failed to create intermediate folder: ${part}`);\r\n }\r\n\r\n currentFolderId = folder.data.id;\r\n } else {\r\n // Folder exists, proceed deeper\r\n currentFolderId = response.data.files[0].id!;\r\n }\r\n }\r\n\r\n return currentFolderId;\r\n}\r\n\r\n\r\n/**\r\n * Resolve a folder ID or path.\r\n * If it's a path (starts with '/'), resolve it.\r\n * If no folder is provided, return 'root'.\r\n */\r\nasync function resolveFolderId(input: string | undefined): Promise<string> {\r\n if (!input) return 'root';\r\n\r\n if (input.startsWith('/')) {\r\n // Input is a path\r\n return resolvePath(input);\r\n } else {\r\n // Input is a folder ID, return as-is\r\n return input;\r\n }\r\n}\r\n\r\n/**\r\n * For text-based files, ensure they have a valid extension.\r\n */\r\nfunction validateTextFileExtension(name: string) {\r\n const ext = getExtensionFromFilename(name);\r\n if (!['txt', 'md'].includes(ext)) {\r\n throw new Error(\"File name must end with .txt or .md for text files.\");\r\n }\r\n}\r\n\r\n/**\r\n * Convert A1 notation to GridRange for Google Sheets API\r\n */\r\nfunction convertA1ToGridRange(a1Notation: string, sheetId: number): any {\r\n // Regular expression to match A1 notation like \"A1\", \"B2:D5\", \"A:A\", \"1:1\"\r\n const rangeRegex = /^([A-Z]*)([0-9]*)(:([A-Z]*)([0-9]*))?$/;\r\n const match = a1Notation.match(rangeRegex);\r\n \r\n if (!match) {\r\n throw new Error(`Invalid A1 notation: ${a1Notation}`);\r\n }\r\n \r\n const [, startCol, startRow, , endCol, endRow] = match;\r\n \r\n const gridRange: any = { sheetId };\r\n \r\n // Convert column letters to numbers (A=0, B=1, etc.)\r\n const colToNum = (col: string): number => {\r\n let num = 0;\r\n for (let i = 0; i < col.length; i++) {\r\n num = num * 26 + (col.charCodeAt(i) - 'A'.charCodeAt(0) + 1);\r\n }\r\n return num - 1;\r\n };\r\n \r\n // Set start indices\r\n if (startCol) gridRange.startColumnIndex = colToNum(startCol);\r\n if (startRow) gridRange.startRowIndex = parseInt(startRow) - 1;\r\n \r\n // Set end indices (exclusive)\r\n if (endCol) {\r\n gridRange.endColumnIndex = colToNum(endCol) + 1;\r\n } else if (startCol && !endCol) {\r\n gridRange.endColumnIndex = gridRange.startColumnIndex + 1;\r\n }\r\n \r\n if (endRow) {\r\n gridRange.endRowIndex = parseInt(endRow);\r\n } else if (startRow && !endRow) {\r\n gridRange.endRowIndex = gridRange.startRowIndex + 1;\r\n }\r\n \r\n return gridRange;\r\n}\r\n\r\n/**\r\n * Check if a file with the given name already exists in the specified folder.\r\n * Returns the file ID if it exists, null otherwise.\r\n */\r\nasync function checkFileExists(name: string, parentFolderId: string = 'root'): Promise<string | null> {\r\n try {\r\n const escapedName = name.replace(/\\\\/g, \"\\\\\\\\\").replace(/'/g, \"\\\\'\");\r\n const query = `name = '${escapedName}' and '${parentFolderId}' in parents and trashed = false`;\r\n \r\n const res = await drive.files.list({\r\n q: query,\r\n fields: 'files(id, name, mimeType)',\r\n pageSize: 1,\r\n includeItemsFromAllDrives: true,\r\n supportsAllDrives: true\r\n });\r\n \r\n if (res.data.files && res.data.files.length > 0) {\r\n return res.data.files[0].id || null;\r\n }\r\n return null;\r\n } catch (error) {\r\n log('Error checking file existence:', error);\r\n return null;\r\n }\r\n}\r\n\r\n// -----------------------------------------------------------------------------\r\n// INPUT VALIDATION SCHEMAS\r\n// -----------------------------------------------------------------------------\r\nconst SearchSchema = z.object({\r\n query: z.string().min(1, \"Search query is required\"),\r\n pageSize: z.number().int().min(1).max(100).optional(),\r\n pageToken: z.string().optional()\r\n});\r\n\r\nconst CreateTextFileSchema = z.object({\r\n name: z.string().min(1, \"File name is required\"),\r\n content: z.string(),\r\n parentFolderId: z.string().optional()\r\n});\r\n\r\nconst UpdateTextFileSchema = z.object({\r\n fileId: z.string().min(1, \"File ID is required\"),\r\n content: z.string(),\r\n name: z.string().optional()\r\n});\r\n\r\nconst CreateFolderSchema = z.object({\r\n name: z.string().min(1, \"Folder name is required\"),\r\n parent: z.string().optional()\r\n});\r\n\r\nconst ListFolderSchema = z.object({\r\n folderId: z.string().optional(),\r\n pageSize: z.number().int().min(1).max(100).optional(),\r\n pageToken: z.string().optional()\r\n});\r\n\r\nconst DeleteItemSchema = z.object({\r\n itemId: z.string().min(1, \"Item ID is required\")\r\n});\r\n\r\nconst RenameItemSchema = z.object({\r\n itemId: z.string().min(1, \"Item ID is required\"),\r\n newName: z.string().min(1, \"New name is required\")\r\n});\r\n\r\nconst MoveItemSchema = z.object({\r\n itemId: z.string().min(1, \"Item ID is required\"),\r\n destinationFolderId: z.string().optional()\r\n});\r\n\r\nconst CreateGoogleDocSchema = z.object({\r\n name: z.string().min(1, \"Document name is required\"),\r\n content: z.string(),\r\n parentFolderId: z.string().optional()\r\n});\r\n\r\nconst UpdateGoogleDocSchema = z.object({\r\n documentId: z.string().min(1, \"Document ID is required\"),\r\n content: z.string()\r\n});\r\n\r\nconst CreateGoogleSheetSchema = z.object({\r\n name: z.string().min(1, \"Sheet name is required\"),\r\n data: z.array(z.array(z.string())),\r\n parentFolderId: z.string().optional(),\r\n valueInputOption: z.enum([\"RAW\", \"USER_ENTERED\"]).optional()\r\n});\r\n\r\nconst UpdateGoogleSheetSchema = z.object({\r\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\r\n range: z.string().min(1, \"Range is required\"),\r\n data: z.array(z.array(z.string())),\r\n valueInputOption: z.enum([\"RAW\", \"USER_ENTERED\"]).optional()\r\n});\r\n\r\nconst GetGoogleSheetContentSchema = z.object({\r\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\r\n range: z.string().min(1, \"Range is required\")\r\n});\r\n\r\nconst FormatGoogleSheetCellsSchema = z.object({\r\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\r\n range: z.string().min(1, \"Range is required\"),\r\n backgroundColor: z.object({\r\n red: z.number().min(0).max(1).optional(),\r\n green: z.number().min(0).max(1).optional(),\r\n blue: z.number().min(0).max(1).optional()\r\n }).optional(),\r\n horizontalAlignment: z.enum([\"LEFT\", \"CENTER\", \"RIGHT\"]).optional(),\r\n verticalAlignment: z.enum([\"TOP\", \"MIDDLE\", \"BOTTOM\"]).optional(),\r\n wrapStrategy: z.enum([\"OVERFLOW_CELL\", \"CLIP\", \"WRAP\"]).optional()\r\n});\r\n\r\nconst FormatGoogleSheetTextSchema = z.object({\r\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\r\n range: z.string().min(1, \"Range is required\"),\r\n bold: z.boolean().optional(),\r\n italic: z.boolean().optional(),\r\n strikethrough: z.boolean().optional(),\r\n underline: z.boolean().optional(),\r\n fontSize: z.number().min(1).optional(),\r\n fontFamily: z.string().optional(),\r\n foregroundColor: z.object({\r\n red: z.number().min(0).max(1).optional(),\r\n green: z.number().min(0).max(1).optional(),\r\n blue: z.number().min(0).max(1).optional()\r\n }).optional()\r\n});\r\n\r\nconst FormatGoogleSheetNumbersSchema = z.object({\r\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\r\n range: z.string().min(1, \"Range is required\"),\r\n pattern: z.string().min(1, \"Pattern is required\"),\r\n type: z.enum([\"NUMBER\", \"CURRENCY\", \"PERCENT\", \"DATE\", \"TIME\", \"DATE_TIME\", \"SCIENTIFIC\"]).optional()\r\n});\r\n\r\nconst SetGoogleSheetBordersSchema = z.object({\r\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\r\n range: z.string().min(1, \"Range is required\"),\r\n style: z.enum([\"SOLID\", \"DASHED\", \"DOTTED\", \"DOUBLE\"]),\r\n width: z.number().min(1).max(3).optional(),\r\n color: z.object({\r\n red: z.number().min(0).max(1).optional(),\r\n green: z.number().min(0).max(1).optional(),\r\n blue: z.number().min(0).max(1).optional()\r\n }).optional(),\r\n top: z.boolean().optional(),\r\n bottom: z.boolean().optional(),\r\n left: z.boolean().optional(),\r\n right: z.boolean().optional(),\r\n innerHorizontal: z.boolean().optional(),\r\n innerVertical: z.boolean().optional()\r\n});\r\n\r\nconst MergeGoogleSheetCellsSchema = z.object({\r\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\r\n range: z.string().min(1, \"Range is required\"),\r\n mergeType: z.enum([\"MERGE_ALL\", \"MERGE_COLUMNS\", \"MERGE_ROWS\"])\r\n});\r\n\r\nconst AddGoogleSheetConditionalFormatSchema = z.object({\r\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\r\n range: z.string().min(1, \"Range is required\"),\r\n condition: z.object({\r\n type: z.enum([\"NUMBER_GREATER\", \"NUMBER_LESS\", \"TEXT_CONTAINS\", \"TEXT_STARTS_WITH\", \"TEXT_ENDS_WITH\", \"CUSTOM_FORMULA\"]),\r\n value: z.string()\r\n }),\r\n format: z.object({\r\n backgroundColor: z.object({\r\n red: z.number().min(0).max(1).optional(),\r\n green: z.number().min(0).max(1).optional(),\r\n blue: z.number().min(0).max(1).optional()\r\n }).optional(),\r\n textFormat: z.object({\r\n bold: z.boolean().optional(),\r\n foregroundColor: z.object({\r\n red: z.number().min(0).max(1).optional(),\r\n green: z.number().min(0).max(1).optional(),\r\n blue: z.number().min(0).max(1).optional()\r\n }).optional()\r\n }).optional()\r\n })\r\n});\r\n\r\nconst CreateGoogleSlidesSchema = z.object({\r\n name: z.string().min(1, \"Presentation name is required\"),\r\n slides: z.array(z.object({\r\n title: z.string(),\r\n content: z.string()\r\n })).min(1, \"At least one slide is required\"),\r\n parentFolderId: z.string().optional()\r\n});\r\n\r\nconst UpdateGoogleSlidesSchema = z.object({\r\n presentationId: z.string().min(1, \"Presentation ID is required\"),\r\n slides: z.array(z.object({\r\n title: z.string(),\r\n content: z.string()\r\n })).min(1, \"At least one slide is required\")\r\n});\r\n\r\nconst FormatGoogleDocTextSchema = z.object({\r\n documentId: z.string().min(1, \"Document ID is required\"),\r\n startIndex: z.number().min(1, \"Start index must be at least 1\"),\r\n endIndex: z.number().min(1, \"End index must be at least 1\"),\r\n bold: z.boolean().optional(),\r\n italic: z.boolean().optional(),\r\n underline: z.boolean().optional(),\r\n strikethrough: z.boolean().optional(),\r\n fontSize: z.number().optional(),\r\n foregroundColor: z.object({\r\n red: z.number().min(0).max(1).optional(),\r\n green: z.number().min(0).max(1).optional(),\r\n blue: z.number().min(0).max(1).optional()\r\n }).optional()\r\n});\r\n\r\nconst FormatGoogleDocParagraphSchema = z.object({\r\n documentId: z.string().min(1, \"Document ID is required\"),\r\n startIndex: z.number().min(1, \"Start index must be at least 1\"),\r\n endIndex: z.number().min(1, \"End index must be at least 1\"),\r\n namedStyleType: z.enum(['NORMAL_TEXT', 'TITLE', 'SUBTITLE', 'HEADING_1', 'HEADING_2', 'HEADING_3', 'HEADING_4', 'HEADING_5', 'HEADING_6']).optional(),\r\n alignment: z.enum(['START', 'CENTER', 'END', 'JUSTIFIED']).optional(),\r\n lineSpacing: z.number().optional(),\r\n spaceAbove: z.number().optional(),\r\n spaceBelow: z.number().optional()\r\n});\r\n\r\nconst GetGoogleDocContentSchema = z.object({\r\n documentId: z.string().min(1, \"Document ID is required\")\r\n});\r\n\r\n// Google Slides Formatting Schemas\r\nconst GetGoogleSlidesContentSchema = z.object({\r\n presentationId: z.string().min(1, \"Presentation ID is required\"),\r\n slideIndex: z.number().min(0).optional()\r\n});\r\n\r\nconst FormatGoogleSlidesTextSchema = z.object({\r\n presentationId: z.string().min(1, \"Presentation ID is required\"),\r\n objectId: z.string().min(1, \"Object ID is required\"),\r\n startIndex: z.number().min(0).optional(),\r\n endIndex: z.number().min(0).optional(),\r\n bold: z.boolean().optional(),\r\n italic: z.boolean().optional(),\r\n underline: z.boolean().optional(),\r\n strikethrough: z.boolean().optional(),\r\n fontSize: z.number().optional(),\r\n fontFamily: z.string().optional(),\r\n foregroundColor: z.object({\r\n red: z.number().min(0).max(1).optional(),\r\n green: z.number().min(0).max(1).optional(),\r\n blue: z.number().min(0).max(1).optional()\r\n }).optional()\r\n});\r\n\r\nconst FormatGoogleSlidesParagraphSchema = z.object({\r\n presentationId: z.string().min(1, \"Presentation ID is required\"),\r\n objectId: z.string().min(1, \"Object ID is required\"),\r\n alignment: z.enum(['START', 'CENTER', 'END', 'JUSTIFIED']).optional(),\r\n lineSpacing: z.number().optional(),\r\n bulletStyle: z.enum(['NONE', 'DISC', 'ARROW', 'SQUARE', 'DIAMOND', 'STAR', 'NUMBERED']).optional()\r\n});\r\n\r\nconst StyleGoogleSlidesShapeSchema = z.object({\r\n presentationId: z.string().min(1, \"Presentation ID is required\"),\r\n objectId: z.string().min(1, \"Shape object ID is required\"),\r\n backgroundColor: z.object({\r\n red: z.number().min(0).max(1).optional(),\r\n green: z.number().min(0).max(1).optional(),\r\n blue: z.number().min(0).max(1).optional(),\r\n alpha: z.number().min(0).max(1).optional()\r\n }).optional(),\r\n outlineColor: z.object({\r\n red: z.number().min(0).max(1).optional(),\r\n green: z.number().min(0).max(1).optional(),\r\n blue: z.number().min(0).max(1).optional()\r\n }).optional(),\r\n outlineWeight: z.number().optional(),\r\n outlineDashStyle: z.enum(['SOLID', 'DOT', 'DASH', 'DASH_DOT', 'LONG_DASH', 'LONG_DASH_DOT']).optional()\r\n});\r\n\r\nconst SetGoogleSlidesBackgroundSchema = z.object({\r\n presentationId: z.string().min(1, \"Presentation ID is required\"),\r\n pageObjectIds: z.array(z.string()).min(1, \"At least one page object ID is required\"),\r\n backgroundColor: z.object({\r\n red: z.number().min(0).max(1).optional(),\r\n green: z.number().min(0).max(1).optional(),\r\n blue: z.number().min(0).max(1).optional(),\r\n alpha: z.number().min(0).max(1).optional()\r\n })\r\n});\r\n\r\nconst CreateGoogleSlidesTextBoxSchema = z.object({\r\n presentationId: z.string().min(1, \"Presentation ID is required\"),\r\n pageObjectId: z.string().min(1, \"Page object ID is required\"),\r\n text: z.string().min(1, \"Text content is required\"),\r\n x: z.number(),\r\n y: z.number(),\r\n width: z.number(),\r\n height: z.number(),\r\n fontSize: z.number().optional(),\r\n bold: z.boolean().optional(),\r\n italic: z.boolean().optional()\r\n});\r\n\r\nconst CreateGoogleSlidesShapeSchema = z.object({\r\n presentationId: z.string().min(1, \"Presentation ID is required\"),\r\n pageObjectId: z.string().min(1, \"Page object ID is required\"),\r\n shapeType: z.enum(['RECTANGLE', 'ELLIPSE', 'DIAMOND', 'TRIANGLE', 'STAR', 'ROUND_RECTANGLE', 'ARROW']),\r\n x: z.number(),\r\n y: z.number(),\r\n width: z.number(),\r\n height: z.number(),\r\n backgroundColor: z.object({\r\n red: z.number().min(0).max(1).optional(),\r\n green: z.number().min(0).max(1).optional(),\r\n blue: z.number().min(0).max(1).optional(),\r\n alpha: z.number().min(0).max(1).optional()\r\n }).optional()\r\n});\r\n\r\nconst GetGoogleSlidesSpeakerNotesSchema = z.object({\r\n presentationId: z.string().min(1, \"Presentation ID is required\"),\r\n slideIndex: z.number().min(0, \"Slide index must be non-negative\")\r\n});\r\n\r\nconst UpdateGoogleSlidesSpeakerNotesSchema = z.object({\r\n presentationId: z.string().min(1, \"Presentation ID is required\"),\r\n slideIndex: z.number().min(0, \"Slide index must be non-negative\"),\r\n notes: z.string()\r\n});\r\n\r\nconst UploadFileSchema = z.object({\r\n localPath: z.string().min(1, \"Local file path is required\"),\r\n name: z.string().optional(),\r\n parentFolderId: z.string().optional(),\r\n mimeType: z.string().optional()\r\n});\r\n\r\n// -----------------------------------------------------------------------------\r\n// SERVER SETUP\r\n// -----------------------------------------------------------------------------\r\nconst server = new Server(\r\n {\r\n name: \"google-drive-mcp\",\r\n version: VERSION,\r\n },\r\n {\r\n capabilities: {\r\n resources: {},\r\n tools: {},\r\n },\r\n },\r\n);\r\n\r\n// -----------------------------------------------------------------------------\r\n// AUTHENTICATION HELPER\r\n// -----------------------------------------------------------------------------\r\nasync function ensureAuthenticated() {\r\n if (!authClient) {\r\n // If authentication is already in progress, wait for it\r\n if (authenticationPromise) {\r\n log('Authentication already in progress, waiting...');\r\n authClient = await authenticationPromise;\r\n return;\r\n }\r\n \r\n log('Initializing authentication');\r\n // Store the promise to prevent concurrent authentication attempts\r\n authenticationPromise = authenticate();\r\n \r\n try {\r\n authClient = await authenticationPromise;\r\n log('Authentication complete', {\r\n authClientType: authClient?.constructor?.name,\r\n hasCredentials: !!authClient?.credentials,\r\n hasAccessToken: !!authClient?.credentials?.access_token\r\n });\r\n // Ensure drive service is created with auth\r\n ensureDriveService();\r\n } finally {\r\n // Clear the promise after completion (success or failure)\r\n authenticationPromise = null;\r\n }\r\n }\r\n \r\n // If we already have authClient, ensure drive is up to date\r\n ensureDriveService();\r\n}\r\n\r\n// -----------------------------------------------------------------------------\r\n// MCP REQUEST HANDLERS\r\n// -----------------------------------------------------------------------------\r\n\r\nserver.setRequestHandler(ListResourcesRequestSchema, async (request) => {\r\n await ensureAuthenticated();\r\n log('Handling ListResources request', { params: request.params });\r\n const pageSize = 10;\r\n const params: {\r\n pageSize: number,\r\n fields: string,\r\n pageToken?: string,\r\n q: string,\r\n includeItemsFromAllDrives: boolean,\r\n supportsAllDrives: boolean\r\n } = {\r\n pageSize,\r\n fields: \"nextPageToken, files(id, name, mimeType)\",\r\n q: `trashed = false`,\r\n includeItemsFromAllDrives: true,\r\n supportsAllDrives: true\r\n };\r\n\r\n if (request.params?.cursor) {\r\n params.pageToken = request.params.cursor;\r\n }\r\n\r\n const res = await drive.files.list(params);\r\n log('Listed files', { count: res.data.files?.length });\r\n const files = res.data.files || [];\r\n\r\n return {\r\n resources: files.map((file: drive_v3.Schema$File) => ({\r\n uri: `gdrive:///${file.id}`,\r\n mimeType: file.mimeType || 'application/octet-stream',\r\n name: file.name || 'Untitled',\r\n })),\r\n nextCursor: res.data.nextPageToken,\r\n };\r\n});\r\n\r\nserver.setRequestHandler(ReadResourceRequestSchema, async (request) => {\r\n await ensureAuthenticated();\r\n log('Handling ReadResource request', { uri: request.params.uri });\r\n const fileId = request.params.uri.replace(\"gdrive:///\", \"\");\r\n\r\n const file = await drive.files.get({\r\n fileId,\r\n fields: \"mimeType\",\r\n supportsAllDrives: true\r\n });\r\n const mimeType = file.data.mimeType;\r\n\r\n if (!mimeType) {\r\n throw new Error(\"File has no MIME type.\");\r\n }\r\n\r\n if (mimeType.startsWith(\"application/vnd.google-apps\")) {\r\n // Export logic for Google Docs/Sheets/Slides\r\n let exportMimeType;\r\n switch (mimeType) {\r\n case \"application/vnd.google-apps.document\": exportMimeType = \"text/markdown\"; break;\r\n case \"application/vnd.google-apps.spreadsheet\": exportMimeType = \"text/csv\"; break;\r\n case \"application/vnd.google-apps.presentation\": exportMimeType = \"text/plain\"; break;\r\n case \"application/vnd.google-apps.drawing\": exportMimeType = \"image/png\"; break;\r\n default: exportMimeType = \"text/plain\"; break;\r\n }\r\n\r\n const res = await drive.files.export(\r\n { fileId, mimeType: exportMimeType, supportsAllDrives: true },\r\n { responseType: \"text\" },\r\n );\r\n\r\n log('Successfully read resource', { fileId, mimeType });\r\n return {\r\n contents: [\r\n {\r\n uri: request.params.uri,\r\n mimeType: exportMimeType,\r\n text: res.data,\r\n },\r\n ],\r\n };\r\n } else {\r\n // Regular file download\r\n const res = await drive.files.get(\r\n { fileId, alt: \"media\", supportsAllDrives: true },\r\n { responseType: \"arraybuffer\" },\r\n );\r\n const contentMime = mimeType || \"application/octet-stream\";\r\n\r\n if (contentMime.startsWith(\"text/\") || contentMime === \"application/json\") {\r\n return {\r\n contents: [\r\n {\r\n uri: request.params.uri,\r\n mimeType: contentMime,\r\n text: Buffer.from(res.data as ArrayBuffer).toString(\"utf-8\"),\r\n },\r\n ],\r\n };\r\n } else {\r\n return {\r\n contents: [\r\n {\r\n uri: request.params.uri,\r\n mimeType: contentMime,\r\n blob: Buffer.from(res.data as ArrayBuffer).toString(\"base64\"),\r\n },\r\n ],\r\n };\r\n }\r\n }\r\n});\r\n\r\nserver.setRequestHandler(ListToolsRequestSchema, async () => {\r\n return {\r\n tools: [\r\n {\r\n name: \"search\",\r\n description: \"Search for files in Google Drive\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n query: { type: \"string\", description: \"Search query\" },\r\n pageSize: { type: \"number\", description: \"Results per page (default 50, max 100)\" },\r\n pageToken: { type: \"string\", description: \"Token for next page of results\" }\r\n },\r\n required: [\"query\"],\r\n },\r\n },\r\n {\r\n name: \"createTextFile\",\r\n description: \"Create a new text or markdown file\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n name: { type: \"string\", description: \"File name (.txt or .md)\" },\r\n content: { type: \"string\", description: \"File content\" },\r\n parentFolderId: { type: \"string\", description: \"Optional parent folder ID\", optional: true }\r\n },\r\n required: [\"name\", \"content\"]\r\n }\r\n },\r\n {\r\n name: \"updateTextFile\",\r\n description: \"Update an existing text or markdown file\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n fileId: { type: \"string\", description: \"ID of the file to update\" },\r\n content: { type: \"string\", description: \"New file content\" },\r\n name: { type: \"string\", description: \"Optional new name (.txt or .md)\", optional: true }\r\n },\r\n required: [\"fileId\", \"content\"]\r\n }\r\n },\r\n {\r\n name: \"createFolder\",\r\n description: \"Create a new folder in Google Drive\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n name: { type: \"string\", description: \"Folder name\" },\r\n parent: { type: \"string\", description: \"Optional parent folder ID or path\", optional: true }\r\n },\r\n required: [\"name\"]\r\n }\r\n },\r\n {\r\n name: \"listFolder\",\r\n description: \"List contents of a folder (defaults to root)\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n folderId: { type: \"string\", description: \"Folder ID\", optional: true },\r\n pageSize: { type: \"number\", description: \"Items to return (default 50, max 100)\", optional: true },\r\n pageToken: { type: \"string\", description: \"Token for next page\", optional: true }\r\n }\r\n }\r\n },\r\n {\r\n name: \"deleteItem\",\r\n description: \"Move a file or folder to trash (can be restored from Google Drive trash)\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n itemId: { type: \"string\", description: \"ID of the item to delete\" }\r\n },\r\n required: [\"itemId\"]\r\n }\r\n },\r\n {\r\n name: \"renameItem\",\r\n description: \"Rename a file or folder\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n itemId: { type: \"string\", description: \"ID of the item to rename\" },\r\n newName: { type: \"string\", description: \"New name\" }\r\n },\r\n required: [\"itemId\", \"newName\"]\r\n }\r\n },\r\n {\r\n name: \"moveItem\",\r\n description: \"Move a file or folder\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n itemId: { type: \"string\", description: \"ID of the item to move\" },\r\n destinationFolderId: { type: \"string\", description: \"Destination folder ID\", optional: true }\r\n },\r\n required: [\"itemId\"]\r\n }\r\n },\r\n {\r\n name: \"createGoogleDoc\",\r\n description: \"Create a new Google Doc\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n name: { type: \"string\", description: \"Doc name\" },\r\n content: { type: \"string\", description: \"Doc content\" },\r\n parentFolderId: { type: \"string\", description: \"Parent folder ID\", optional: true }\r\n },\r\n required: [\"name\", \"content\"]\r\n }\r\n },\r\n {\r\n name: \"updateGoogleDoc\",\r\n description: \"Update an existing Google Doc\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n documentId: { type: \"string\", description: \"Doc ID\" },\r\n content: { type: \"string\", description: \"New content\" }\r\n },\r\n required: [\"documentId\", \"content\"]\r\n }\r\n },\r\n {\r\n name: \"createGoogleSheet\",\r\n description: \"Create a new Google Sheet. By default uses RAW mode which stores values as-is. Set valueInputOption to 'USER_ENTERED' only when you need formulas to be evaluated.\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n name: { type: \"string\", description: \"Sheet name\" },\r\n data: {\r\n type: \"array\",\r\n description: \"Data as array of arrays\",\r\n items: { type: \"array\", items: { type: \"string\" } }\r\n },\r\n parentFolderId: { type: \"string\", description: \"Parent folder ID (defaults to root)\", optional: true },\r\n valueInputOption: {\r\n type: \"string\",\r\n enum: [\"RAW\", \"USER_ENTERED\"],\r\n description: \"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().\"\r\n }\r\n },\r\n required: [\"name\", \"data\"]\r\n }\r\n },\r\n {\r\n name: \"updateGoogleSheet\",\r\n description: \"Update an existing Google Sheet. By default uses RAW mode which stores values as-is. Set valueInputOption to 'USER_ENTERED' only when you need formulas to be evaluated.\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n spreadsheetId: { type: \"string\", description: \"Sheet ID\" },\r\n range: { type: \"string\", description: \"Range to update (e.g., 'Sheet1!A1:C10')\" },\r\n data: {\r\n type: \"array\",\r\n description: \"2D array of values to write\",\r\n items: { type: \"array\", items: { type: \"string\" } }\r\n },\r\n valueInputOption: {\r\n type: \"string\",\r\n enum: [\"RAW\", \"USER_ENTERED\"],\r\n description: \"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().\"\r\n }\r\n },\r\n required: [\"spreadsheetId\", \"range\", \"data\"]\r\n }\r\n },\r\n {\r\n name: \"getGoogleSheetContent\",\r\n description: \"Get content of a Google Sheet with cell information\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\r\n range: { type: \"string\", description: \"Range to get (e.g., 'Sheet1!A1:C10')\" }\r\n },\r\n required: [\"spreadsheetId\", \"range\"]\r\n }\r\n },\r\n {\r\n name: \"formatGoogleSheetCells\",\r\n description: \"Format cells in a Google Sheet (background, borders, alignment)\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\r\n range: { type: \"string\", description: \"Range to format (e.g., 'A1:C10')\" },\r\n backgroundColor: {\r\n type: \"object\",\r\n description: \"Background color (RGB values 0-1)\",\r\n properties: {\r\n red: { type: \"number\", optional: true },\r\n green: { type: \"number\", optional: true },\r\n blue: { type: \"number\", optional: true }\r\n },\r\n optional: true\r\n },\r\n horizontalAlignment: {\r\n type: \"string\",\r\n description: \"Horizontal alignment\",\r\n enum: [\"LEFT\", \"CENTER\", \"RIGHT\"],\r\n optional: true\r\n },\r\n verticalAlignment: {\r\n type: \"string\",\r\n description: \"Vertical alignment\",\r\n enum: [\"TOP\", \"MIDDLE\", \"BOTTOM\"],\r\n optional: true\r\n },\r\n wrapStrategy: {\r\n type: \"string\",\r\n description: \"Text wrapping\",\r\n enum: [\"OVERFLOW_CELL\", \"CLIP\", \"WRAP\"],\r\n optional: true\r\n }\r\n },\r\n required: [\"spreadsheetId\", \"range\"]\r\n }\r\n },\r\n {\r\n name: \"formatGoogleSheetText\",\r\n description: \"Apply text formatting to cells in a Google Sheet\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\r\n range: { type: \"string\", description: \"Range to format (e.g., 'A1:C10')\" },\r\n bold: { type: \"boolean\", description: \"Make text bold\", optional: true },\r\n italic: { type: \"boolean\", description: \"Make text italic\", optional: true },\r\n strikethrough: { type: \"boolean\", description: \"Strikethrough text\", optional: true },\r\n underline: { type: \"boolean\", description: \"Underline text\", optional: true },\r\n fontSize: { type: \"number\", description: \"Font size in points\", optional: true },\r\n fontFamily: { type: \"string\", description: \"Font family name\", optional: true },\r\n foregroundColor: {\r\n type: \"object\",\r\n description: \"Text color (RGB values 0-1)\",\r\n properties: {\r\n red: { type: \"number\", optional: true },\r\n green: { type: \"number\", optional: true },\r\n blue: { type: \"number\", optional: true }\r\n },\r\n optional: true\r\n }\r\n },\r\n required: [\"spreadsheetId\", \"range\"]\r\n }\r\n },\r\n {\r\n name: \"formatGoogleSheetNumbers\",\r\n description: \"Apply number formatting to cells in a Google Sheet\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\r\n range: { type: \"string\", description: \"Range to format (e.g., 'A1:C10')\" },\r\n pattern: {\r\n type: \"string\",\r\n description: \"Number format pattern (e.g., '#,##0.00', 'yyyy-mm-dd', '$#,##0.00', '0.00%')\"\r\n },\r\n type: {\r\n type: \"string\",\r\n description: \"Format type\",\r\n enum: [\"NUMBER\", \"CURRENCY\", \"PERCENT\", \"DATE\", \"TIME\", \"DATE_TIME\", \"SCIENTIFIC\"],\r\n optional: true\r\n }\r\n },\r\n required: [\"spreadsheetId\", \"range\", \"pattern\"]\r\n }\r\n },\r\n {\r\n name: \"setGoogleSheetBorders\",\r\n description: \"Set borders for cells in a Google Sheet\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\r\n range: { type: \"string\", description: \"Range to format (e.g., 'A1:C10')\" },\r\n style: {\r\n type: \"string\",\r\n description: \"Border style\",\r\n enum: [\"SOLID\", \"DASHED\", \"DOTTED\", \"DOUBLE\"]\r\n },\r\n width: { type: \"number\", description: \"Border width (1-3)\", optional: true },\r\n color: {\r\n type: \"object\",\r\n description: \"Border color (RGB values 0-1)\",\r\n properties: {\r\n red: { type: \"number\", optional: true },\r\n green: { type: \"number\", optional: true },\r\n blue: { type: \"number\", optional: true }\r\n },\r\n optional: true\r\n },\r\n top: { type: \"boolean\", description: \"Apply to top border\", optional: true },\r\n bottom: { type: \"boolean\", description: \"Apply to bottom border\", optional: true },\r\n left: { type: \"boolean\", description: \"Apply to left border\", optional: true },\r\n right: { type: \"boolean\", description: \"Apply to right border\", optional: true },\r\n innerHorizontal: { type: \"boolean\", description: \"Apply to inner horizontal borders\", optional: true },\r\n innerVertical: { type: \"boolean\", description: \"Apply to inner vertical borders\", optional: true }\r\n },\r\n required: [\"spreadsheetId\", \"range\", \"style\"]\r\n }\r\n },\r\n {\r\n name: \"mergeGoogleSheetCells\",\r\n description: \"Merge cells in a Google Sheet\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\r\n range: { type: \"string\", description: \"Range to merge (e.g., 'A1:C3')\" },\r\n mergeType: {\r\n type: \"string\",\r\n description: \"Merge type\",\r\n enum: [\"MERGE_ALL\", \"MERGE_COLUMNS\", \"MERGE_ROWS\"]\r\n }\r\n },\r\n required: [\"spreadsheetId\", \"range\", \"mergeType\"]\r\n }\r\n },\r\n {\r\n name: \"addGoogleSheetConditionalFormat\",\r\n description: \"Add conditional formatting to a Google Sheet\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\r\n range: { type: \"string\", description: \"Range to apply formatting (e.g., 'A1:C10')\" },\r\n condition: {\r\n type: \"object\",\r\n description: \"Condition configuration\",\r\n properties: {\r\n type: {\r\n type: \"string\",\r\n description: \"Condition type\",\r\n enum: [\"NUMBER_GREATER\", \"NUMBER_LESS\", \"TEXT_CONTAINS\", \"TEXT_STARTS_WITH\", \"TEXT_ENDS_WITH\", \"CUSTOM_FORMULA\"]\r\n },\r\n value: { type: \"string\", description: \"Value to compare or formula\" }\r\n }\r\n },\r\n format: {\r\n type: \"object\",\r\n description: \"Format to apply when condition is true\",\r\n properties: {\r\n backgroundColor: {\r\n type: \"object\",\r\n properties: {\r\n red: { type: \"number\", optional: true },\r\n green: { type: \"number\", optional: true },\r\n blue: { type: \"number\", optional: true }\r\n },\r\n optional: true\r\n },\r\n textFormat: {\r\n type: \"object\",\r\n properties: {\r\n bold: { type: \"boolean\", optional: true },\r\n foregroundColor: {\r\n type: \"object\",\r\n properties: {\r\n red: { type: \"number\", optional: true },\r\n green: { type: \"number\", optional: true },\r\n blue: { type: \"number\", optional: true }\r\n },\r\n optional: true\r\n }\r\n },\r\n optional: true\r\n }\r\n }\r\n }\r\n },\r\n required: [\"spreadsheetId\", \"range\", \"condition\", \"format\"]\r\n }\r\n },\r\n {\r\n name: \"createGoogleSlides\",\r\n description: \"Create a new Google Slides presentation\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n name: { type: \"string\", description: \"Presentation name\" },\r\n slides: {\r\n type: \"array\",\r\n description: \"Array of slide objects\",\r\n items: {\r\n type: \"object\",\r\n properties: {\r\n title: { type: \"string\" },\r\n content: { type: \"string\" }\r\n }\r\n }\r\n },\r\n parentFolderId: { type: \"string\", description: \"Parent folder ID (defaults to root)\", optional: true }\r\n },\r\n required: [\"name\", \"slides\"]\r\n }\r\n },\r\n {\r\n name: \"updateGoogleSlides\",\r\n description: \"Update an existing Google Slides presentation\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n presentationId: { type: \"string\", description: \"Presentation ID\" },\r\n slides: {\r\n type: \"array\",\r\n description: \"Array of slide objects to replace existing slides\",\r\n items: {\r\n type: \"object\",\r\n properties: {\r\n title: { type: \"string\" },\r\n content: { type: \"string\" }\r\n }\r\n }\r\n }\r\n },\r\n required: [\"presentationId\", \"slides\"]\r\n }\r\n },\r\n {\r\n name: \"formatGoogleDocText\",\r\n description: \"Apply text formatting to a range in a Google Doc\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n documentId: { type: \"string\", description: \"Document ID\" },\r\n startIndex: { type: \"number\", description: \"Start index (1-based)\" },\r\n endIndex: { type: \"number\", description: \"End index (1-based)\" },\r\n bold: { type: \"boolean\", description: \"Make text bold\", optional: true },\r\n italic: { type: \"boolean\", description: \"Make text italic\", optional: true },\r\n underline: { type: \"boolean\", description: \"Underline text\", optional: true },\r\n strikethrough: { type: \"boolean\", description: \"Strikethrough text\", optional: true },\r\n fontSize: { type: \"number\", description: \"Font size in points\", optional: true },\r\n foregroundColor: {\r\n type: \"object\",\r\n description: \"Text color (RGB values 0-1)\",\r\n properties: {\r\n red: { type: \"number\", optional: true },\r\n green: { type: \"number\", optional: true },\r\n blue: { type: \"number\", optional: true }\r\n },\r\n optional: true\r\n }\r\n },\r\n required: [\"documentId\", \"startIndex\", \"endIndex\"]\r\n }\r\n },\r\n {\r\n name: \"formatGoogleDocParagraph\",\r\n description: \"Apply paragraph formatting to a range in a Google Doc\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n documentId: { type: \"string\", description: \"Document ID\" },\r\n startIndex: { type: \"number\", description: \"Start index (1-based)\" },\r\n endIndex: { type: \"number\", description: \"End index (1-based)\" },\r\n namedStyleType: {\r\n type: \"string\",\r\n description: \"Paragraph style\",\r\n enum: [\"NORMAL_TEXT\", \"TITLE\", \"SUBTITLE\", \"HEADING_1\", \"HEADING_2\", \"HEADING_3\", \"HEADING_4\", \"HEADING_5\", \"HEADING_6\"],\r\n optional: true\r\n },\r\n alignment: {\r\n type: \"string\",\r\n description: \"Text alignment\",\r\n enum: [\"START\", \"CENTER\", \"END\", \"JUSTIFIED\"],\r\n optional: true\r\n },\r\n lineSpacing: { type: \"number\", description: \"Line spacing multiplier\", optional: true },\r\n spaceAbove: { type: \"number\", description: \"Space above paragraph in points\", optional: true },\r\n spaceBelow: { type: \"number\", description: \"Space below paragraph in points\", optional: true }\r\n },\r\n required: [\"documentId\", \"startIndex\", \"endIndex\"]\r\n }\r\n },\r\n {\r\n name: \"getGoogleDocContent\",\r\n description: \"Get content of a Google Doc with text indices for formatting\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n documentId: { type: \"string\", description: \"Document ID\" }\r\n },\r\n required: [\"documentId\"]\r\n }\r\n },\r\n {\r\n name: \"getGoogleSlidesContent\",\r\n description: \"Get content of Google Slides with element IDs for formatting\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n presentationId: { type: \"string\", description: \"Presentation ID\" },\r\n slideIndex: { type: \"number\", description: \"Specific slide index (optional)\", optional: true }\r\n },\r\n required: [\"presentationId\"]\r\n }\r\n },\r\n {\r\n name: \"formatGoogleSlidesText\",\r\n description: \"Apply text formatting to elements in Google Slides\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n presentationId: { type: \"string\", description: \"Presentation ID\" },\r\n objectId: { type: \"string\", description: \"Object ID of the text element\" },\r\n startIndex: { type: \"number\", description: \"Start index (0-based)\", optional: true },\r\n endIndex: { type: \"number\", description: \"End index (0-based)\", optional: true },\r\n bold: { type: \"boolean\", description: \"Make text bold\", optional: true },\r\n italic: { type: \"boolean\", description: \"Make text italic\", optional: true },\r\n underline: { type: \"boolean\", description: \"Underline text\", optional: true },\r\n strikethrough: { type: \"boolean\", description: \"Strikethrough text\", optional: true },\r\n fontSize: { type: \"number\", description: \"Font size in points\", optional: true },\r\n fontFamily: { type: \"string\", description: \"Font family name\", optional: true },\r\n foregroundColor: {\r\n type: \"object\",\r\n description: \"Text color (RGB values 0-1)\",\r\n properties: {\r\n red: { type: \"number\", optional: true },\r\n green: { type: \"number\", optional: true },\r\n blue: { type: \"number\", optional: true }\r\n },\r\n optional: true\r\n }\r\n },\r\n required: [\"presentationId\", \"objectId\"]\r\n }\r\n },\r\n {\r\n name: \"formatGoogleSlidesParagraph\",\r\n description: \"Apply paragraph formatting to text in Google Slides\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n presentationId: { type: \"string\", description: \"Presentation ID\" },\r\n objectId: { type: \"string\", description: \"Object ID of the text element\" },\r\n alignment: {\r\n type: \"string\",\r\n description: \"Text alignment\",\r\n enum: [\"START\", \"CENTER\", \"END\", \"JUSTIFIED\"],\r\n optional: true\r\n },\r\n lineSpacing: { type: \"number\", description: \"Line spacing multiplier\", optional: true },\r\n bulletStyle: {\r\n type: \"string\",\r\n description: \"Bullet style\",\r\n enum: [\"NONE\", \"DISC\", \"ARROW\", \"SQUARE\", \"DIAMOND\", \"STAR\", \"NUMBERED\"],\r\n optional: true\r\n }\r\n },\r\n required: [\"presentationId\", \"objectId\"]\r\n }\r\n },\r\n {\r\n name: \"styleGoogleSlidesShape\",\r\n description: \"Style shapes in Google Slides\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n presentationId: { type: \"string\", description: \"Presentation ID\" },\r\n objectId: { type: \"string\", description: \"Shape object ID\" },\r\n backgroundColor: {\r\n type: \"object\",\r\n description: \"Background color (RGBA values 0-1)\",\r\n properties: {\r\n red: { type: \"number\", optional: true },\r\n green: { type: \"number\", optional: true },\r\n blue: { type: \"number\", optional: true },\r\n alpha: { type: \"number\", optional: true }\r\n },\r\n optional: true\r\n },\r\n outlineColor: {\r\n type: \"object\",\r\n description: \"Outline color (RGB values 0-1)\",\r\n properties: {\r\n red: { type: \"number\", optional: true },\r\n green: { type: \"number\", optional: true },\r\n blue: { type: \"number\", optional: true }\r\n },\r\n optional: true\r\n },\r\n outlineWeight: { type: \"number\", description: \"Outline thickness in points\", optional: true },\r\n outlineDashStyle: {\r\n type: \"string\",\r\n description: \"Outline dash style\",\r\n enum: [\"SOLID\", \"DOT\", \"DASH\", \"DASH_DOT\", \"LONG_DASH\", \"LONG_DASH_DOT\"],\r\n optional: true\r\n }\r\n },\r\n required: [\"presentationId\", \"objectId\"]\r\n }\r\n },\r\n {\r\n name: \"setGoogleSlidesBackground\",\r\n description: \"Set background color for slides\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n presentationId: { type: \"string\", description: \"Presentation ID\" },\r\n pageObjectIds: {\r\n type: \"array\",\r\n description: \"Array of slide IDs to update\",\r\n items: { type: \"string\" }\r\n },\r\n backgroundColor: {\r\n type: \"object\",\r\n description: \"Background color (RGBA values 0-1)\",\r\n properties: {\r\n red: { type: \"number\", optional: true },\r\n green: { type: \"number\", optional: true },\r\n blue: { type: \"number\", optional: true },\r\n alpha: { type: \"number\", optional: true }\r\n }\r\n }\r\n },\r\n required: [\"presentationId\", \"pageObjectIds\", \"backgroundColor\"]\r\n }\r\n },\r\n {\r\n name: \"createGoogleSlidesTextBox\",\r\n description: \"Create a text box in Google Slides\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n presentationId: { type: \"string\", description: \"Presentation ID\" },\r\n pageObjectId: { type: \"string\", description: \"Slide ID\" },\r\n text: { type: \"string\", description: \"Text content\" },\r\n x: { type: \"number\", description: \"X position in EMU (1/360000 cm)\" },\r\n y: { type: \"number\", description: \"Y position in EMU\" },\r\n width: { type: \"number\", description: \"Width in EMU\" },\r\n height: { type: \"number\", description: \"Height in EMU\" },\r\n fontSize: { type: \"number\", description: \"Font size in points\", optional: true },\r\n bold: { type: \"boolean\", description: \"Make text bold\", optional: true },\r\n italic: { type: \"boolean\", description: \"Make text italic\", optional: true }\r\n },\r\n required: [\"presentationId\", \"pageObjectId\", \"text\", \"x\", \"y\", \"width\", \"height\"]\r\n }\r\n },\r\n {\r\n name: \"createGoogleSlidesShape\",\r\n description: \"Create a shape in Google Slides\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n presentationId: { type: \"string\", description: \"Presentation ID\" },\r\n pageObjectId: { type: \"string\", description: \"Slide ID\" },\r\n shapeType: {\r\n type: \"string\",\r\n description: \"Shape type\",\r\n enum: [\"RECTANGLE\", \"ELLIPSE\", \"DIAMOND\", \"TRIANGLE\", \"STAR\", \"ROUND_RECTANGLE\", \"ARROW\"]\r\n },\r\n x: { type: \"number\", description: \"X position in EMU\" },\r\n y: { type: \"number\", description: \"Y position in EMU\" },\r\n width: { type: \"number\", description: \"Width in EMU\" },\r\n height: { type: \"number\", description: \"Height in EMU\" },\r\n backgroundColor: {\r\n type: \"object\",\r\n description: \"Fill color (RGBA values 0-1)\",\r\n properties: {\r\n red: { type: \"number\", optional: true },\r\n green: { type: \"number\", optional: true },\r\n blue: { type: \"number\", optional: true },\r\n alpha: { type: \"number\", optional: true }\r\n },\r\n optional: true\r\n }\r\n },\r\n required: [\"presentationId\", \"pageObjectId\", \"shapeType\", \"x\", \"y\", \"width\", \"height\"]\r\n }\r\n },\r\n {\r\n name: \"getGoogleSlidesSpeakerNotes\",\r\n description: \"Get speaker notes from a specific slide in Google Slides\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n presentationId: { type: \"string\", description: \"Presentation ID\" },\r\n slideIndex: { type: \"number\", description: \"Slide index (0-based)\" }\r\n },\r\n required: [\"presentationId\", \"slideIndex\"]\r\n }\r\n },\r\n {\r\n name: \"updateGoogleSlidesSpeakerNotes\",\r\n description: \"Update speaker notes for a specific slide in Google Slides\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n presentationId: { type: \"string\", description: \"Presentation ID\" },\r\n slideIndex: { type: \"number\", description: \"Slide index (0-based)\" },\r\n notes: { type: \"string\", description: \"Speaker notes content\" }\r\n },\r\n required: [\"presentationId\", \"slideIndex\", \"notes\"]\r\n }\r\n },\r\n {\r\n name: \"uploadFile\",\r\n description: \"Upload a local file (any type: image, audio, video, PDF, etc.) to Google Drive\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n localPath: { type: \"string\", description: \"Absolute path to the local file to upload\" },\r\n name: { type: \"string\", description: \"File name in Drive (defaults to local filename)\", optional: true },\r\n parentFolderId: { type: \"string\", description: \"Parent folder ID or path (e.g., '/Work/Projects'). Creates folders if needed. Defaults to root.\", optional: true },\r\n mimeType: { type: \"string\", description: \"MIME type (auto-detected from extension if omitted)\", optional: true }\r\n },\r\n required: [\"localPath\"]\r\n }\r\n }\r\n ]\r\n };\r\n});\r\n\r\n// -----------------------------------------------------------------------------\r\n// TOOL CALL REQUEST HANDLER\r\n// -----------------------------------------------------------------------------\r\n\r\nserver.setRequestHandler(CallToolRequestSchema, async (request) => {\r\n console.error(`[DEBUG] CallTool handler called for tool: ${request.params.name}`);\r\n await ensureAuthenticated();\r\n console.error(`[DEBUG] After ensureAuthenticated - authClient exists: ${!!authClient}, drive exists: ${!!drive}`);\r\n log('Handling tool request', { tool: request.params.name });\r\n\r\n // Helper for error responses\r\n function errorResponse(message: string) {\r\n log('Error', { message });\r\n return { content: [{ type: \"text\", text: `Error: ${message}` }], isError: true };\r\n }\r\n\r\n try {\r\n switch (request.params.name) {\r\n case \"search\": {\r\n const validation = SearchSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const { query: userQuery, pageSize, pageToken } = validation.data;\r\n\r\n const escapedQuery = userQuery.replace(/\\\\/g, \"\\\\\\\\\").replace(/'/g, \"\\\\'\");\r\n const formattedQuery = `fullText contains '${escapedQuery}' and trashed = false`;\r\n\r\n const res = await drive.files.list({\r\n q: formattedQuery,\r\n pageSize: Math.min(pageSize || 50, 100),\r\n pageToken: pageToken,\r\n fields: \"nextPageToken, files(id, name, mimeType, modifiedTime, size)\",\r\n includeItemsFromAllDrives: true,\r\n supportsAllDrives: true\r\n });\r\n\r\n const fileList = res.data.files?.map((f: drive_v3.Schema$File) => `${f.name} (ID: ${f.id}, ${f.mimeType})`).join(\"\\n\") || '';\r\n log('Search results', { query: userQuery, resultCount: res.data.files?.length });\r\n\r\n let response = `Found ${res.data.files?.length ?? 0} files:\\n${fileList}`;\r\n if (res.data.nextPageToken) {\r\n response += `\\n\\nMore results available. Use pageToken: ${res.data.nextPageToken}`;\r\n }\r\n\r\n return {\r\n content: [{ type: \"text\", text: response }],\r\n isError: false,\r\n };\r\n }\r\n\r\n case \"createTextFile\": {\r\n const validation = CreateTextFileSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n validateTextFileExtension(args.name);\r\n const parentFolderId = await resolveFolderId(args.parentFolderId);\r\n\r\n // Check if file already exists\r\n const existingFileId = await checkFileExists(args.name, parentFolderId);\r\n if (existingFileId) {\r\n return errorResponse(\r\n `A file named \"${args.name}\" already exists in this location. ` +\r\n `To update it, use updateTextFile with fileId: ${existingFileId}`\r\n );\r\n }\r\n\r\n const fileMetadata = {\r\n name: args.name,\r\n mimeType: getMimeTypeFromFilename(args.name),\r\n parents: [parentFolderId]\r\n };\r\n\r\n log('About to create file', {\r\n driveExists: !!drive,\r\n authClientExists: !!authClient,\r\n hasAccessToken: !!authClient?.credentials?.access_token,\r\n tokenLength: authClient?.credentials?.access_token?.length\r\n });\r\n\r\n const file = await drive.files.create({\r\n requestBody: fileMetadata,\r\n media: {\r\n mimeType: fileMetadata.mimeType,\r\n body: args.content,\r\n },\r\n supportsAllDrives: true\r\n });\r\n\r\n log('File created successfully', { fileId: file.data?.id });\r\n return {\r\n content: [{\r\n type: \"text\",\r\n text: `Created file: ${file.data?.name || args.name}\\nID: ${file.data?.id || 'unknown'}`\r\n }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"updateTextFile\": {\r\n const validation = UpdateTextFileSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n // Check file MIME type\r\n const existingFile = await drive.files.get({\r\n fileId: args.fileId,\r\n fields: 'mimeType, name, parents',\r\n supportsAllDrives: true\r\n });\r\n\r\n const currentMimeType = existingFile.data.mimeType || 'text/plain';\r\n if (!Object.values(TEXT_MIME_TYPES).includes(currentMimeType)) {\r\n return errorResponse(\"File is not a text or markdown file.\");\r\n }\r\n\r\n const updateMetadata: { name?: string; mimeType?: string } = {};\r\n if (args.name) {\r\n validateTextFileExtension(args.name);\r\n updateMetadata.name = args.name;\r\n updateMetadata.mimeType = getMimeTypeFromFilename(args.name);\r\n }\r\n\r\n const updatedFile = await drive.files.update({\r\n fileId: args.fileId,\r\n requestBody: updateMetadata,\r\n media: {\r\n mimeType: updateMetadata.mimeType || currentMimeType,\r\n body: args.content\r\n },\r\n fields: 'id, name, modifiedTime, webViewLink',\r\n supportsAllDrives: true\r\n });\r\n\r\n return {\r\n content: [{\r\n type: \"text\",\r\n text: `Updated file: ${updatedFile.data.name}\\nModified: ${updatedFile.data.modifiedTime}`\r\n }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"createFolder\": {\r\n const validation = CreateFolderSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const parentFolderId = await resolveFolderId(args.parent);\r\n\r\n // Check if folder already exists\r\n const existingFolderId = await checkFileExists(args.name, parentFolderId);\r\n if (existingFolderId) {\r\n return errorResponse(\r\n `A folder named \"${args.name}\" already exists in this location. ` +\r\n `Folder ID: ${existingFolderId}`\r\n );\r\n }\r\n const folderMetadata = {\r\n name: args.name,\r\n mimeType: FOLDER_MIME_TYPE,\r\n parents: [parentFolderId]\r\n };\r\n\r\n const folder = await drive.files.create({\r\n requestBody: folderMetadata,\r\n fields: 'id, name, webViewLink',\r\n supportsAllDrives: true\r\n });\r\n\r\n log('Folder created successfully', { folderId: folder.data.id, name: folder.data.name });\r\n\r\n return {\r\n content: [{\r\n type: \"text\",\r\n text: `Created folder: ${folder.data.name}\\nID: ${folder.data.id}`\r\n }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"listFolder\": {\r\n const validation = ListFolderSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n // Default to root if no folder specified\r\n const targetFolderId = args.folderId || 'root';\r\n\r\n const res = await drive.files.list({\r\n q: `'${targetFolderId}' in parents and trashed = false`,\r\n pageSize: Math.min(args.pageSize || 50, 100),\r\n pageToken: args.pageToken,\r\n fields: \"nextPageToken, files(id, name, mimeType, modifiedTime, size)\",\r\n orderBy: \"name\",\r\n includeItemsFromAllDrives: true,\r\n supportsAllDrives: true\r\n });\r\n\r\n const files = res.data.files || [];\r\n const formattedFiles = files.map((file: drive_v3.Schema$File) => {\r\n const isFolder = file.mimeType === FOLDER_MIME_TYPE;\r\n return `${isFolder ? '\uD83D\uDCC1' : '\uD83D\uDCC4'} ${file.name} (ID: ${file.id})`;\r\n }).join('\\n');\r\n\r\n let response = `Contents of folder:\\n\\n${formattedFiles}`;\r\n if (res.data.nextPageToken) {\r\n response += `\\n\\nMore items available. Use pageToken: ${res.data.nextPageToken}`;\r\n }\r\n\r\n return {\r\n content: [{ type: \"text\", text: response }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"deleteItem\": {\r\n const validation = DeleteItemSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const item = await drive.files.get({ fileId: args.itemId, fields: 'name', supportsAllDrives: true });\r\n \r\n // Move to trash instead of permanent deletion\r\n await drive.files.update({\r\n fileId: args.itemId,\r\n requestBody: {\r\n trashed: true\r\n },\r\n supportsAllDrives: true\r\n });\r\n\r\n log('Item moved to trash successfully', { itemId: args.itemId, name: item.data.name });\r\n return {\r\n content: [{ type: \"text\", text: `Successfully moved to trash: ${item.data.name}` }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"renameItem\": {\r\n const validation = RenameItemSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n // If it's a text file, check extension\r\n const item = await drive.files.get({ fileId: args.itemId, fields: 'name, mimeType', supportsAllDrives: true });\r\n if (Object.values(TEXT_MIME_TYPES).includes(item.data.mimeType || '')) {\r\n validateTextFileExtension(args.newName);\r\n }\r\n\r\n const updatedItem = await drive.files.update({\r\n fileId: args.itemId,\r\n requestBody: { name: args.newName },\r\n fields: 'id, name, modifiedTime',\r\n supportsAllDrives: true\r\n });\r\n\r\n return {\r\n content: [{\r\n type: \"text\",\r\n text: `Successfully renamed \"${item.data.name}\" to \"${updatedItem.data.name}\"`\r\n }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"moveItem\": {\r\n const validation = MoveItemSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const destinationFolderId = args.destinationFolderId ?\r\n await resolveFolderId(args.destinationFolderId) :\r\n 'root';\r\n\r\n // Check we aren't moving a folder into itself or its descendant\r\n if (args.destinationFolderId === args.itemId) {\r\n return errorResponse(\"Cannot move a folder into itself.\");\r\n }\r\n\r\n const item = await drive.files.get({ fileId: args.itemId, fields: 'name, parents', supportsAllDrives: true });\r\n\r\n // Perform move\r\n await drive.files.update({\r\n fileId: args.itemId,\r\n addParents: destinationFolderId,\r\n removeParents: item.data.parents?.join(',') || '',\r\n fields: 'id, name, parents',\r\n supportsAllDrives: true\r\n });\r\n\r\n // Get the destination folder name for a nice response\r\n const destinationFolder = await drive.files.get({\r\n fileId: destinationFolderId,\r\n fields: 'name',\r\n supportsAllDrives: true\r\n });\r\n\r\n return {\r\n content: [{\r\n type: \"text\",\r\n text: `Successfully moved \"${item.data.name}\" to \"${destinationFolder.data.name}\"`\r\n }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"createGoogleDoc\": {\r\n const validation = CreateGoogleDocSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const parentFolderId = await resolveFolderId(args.parentFolderId);\r\n\r\n // Check if document already exists\r\n const existingFileId = await checkFileExists(args.name, parentFolderId);\r\n if (existingFileId) {\r\n return errorResponse(\r\n `A document named \"${args.name}\" already exists in this location. ` +\r\n `To update it, use updateGoogleDoc with documentId: ${existingFileId}`\r\n );\r\n }\r\n\r\n log('Creating Google Doc', { \r\n authClientExists: !!authClient, \r\n parentFolderId,\r\n authClientType: authClient?.constructor?.name,\r\n accessToken: authClient?.credentials?.access_token ? 'present' : 'missing',\r\n tokenLength: authClient?.credentials?.access_token?.length\r\n });\r\n\r\n // Debug: Try to get current user to verify auth\r\n try {\r\n const aboutResponse = await drive.about.get({ fields: 'user' });\r\n log('Auth verification - current user:', aboutResponse.data.user?.emailAddress);\r\n } catch (authError) {\r\n log('Auth verification failed:', authError instanceof Error ? authError.message : String(authError));\r\n }\r\n\r\n // Create empty doc\r\n let docResponse;\r\n try {\r\n docResponse = await drive.files.create({\r\n requestBody: {\r\n name: args.name,\r\n mimeType: 'application/vnd.google-apps.document',\r\n parents: [parentFolderId]\r\n },\r\n fields: 'id, name, webViewLink',\r\n supportsAllDrives: true\r\n });\r\n } catch (createError: any) {\r\n log('Drive files.create error details:', {\r\n message: createError.message,\r\n code: createError.code,\r\n errors: createError.errors,\r\n status: createError.status\r\n });\r\n throw createError;\r\n }\r\n const doc = docResponse.data;\r\n\r\n const docs = google.docs({ version: 'v1', auth: authClient });\r\n await docs.documents.batchUpdate({\r\n documentId: doc.id!,\r\n requestBody: {\r\n requests: [\r\n {\r\n insertText: { location: { index: 1 }, text: args.content }\r\n },\r\n // Ensure the text is formatted as normal text, not as a header\r\n {\r\n updateParagraphStyle: {\r\n range: {\r\n startIndex: 1,\r\n endIndex: args.content.length + 1\r\n },\r\n paragraphStyle: {\r\n namedStyleType: 'NORMAL_TEXT'\r\n },\r\n fields: 'namedStyleType'\r\n }\r\n }\r\n ]\r\n }\r\n });\r\n\r\n return {\r\n content: [{ type: \"text\", text: `Created Google Doc: ${doc.name}\\nID: ${doc.id}\\nLink: ${doc.webViewLink}` }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"updateGoogleDoc\": {\r\n const validation = UpdateGoogleDocSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const docs = google.docs({ version: 'v1', auth: authClient });\r\n const document = await docs.documents.get({ documentId: args.documentId });\r\n\r\n // Delete all content\r\n // End index of last piece of content (body's last element, fallback to 1 if none)\r\n const endIndex = document.data.body?.content?.[document.data.body.content.length - 1]?.endIndex || 1;\r\n \r\n // Google Docs API doesn't allow deleting the final newline character\r\n // We need to leave at least one character in the document\r\n const deleteEndIndex = Math.max(1, endIndex - 1);\r\n\r\n if (deleteEndIndex > 1) {\r\n await docs.documents.batchUpdate({\r\n documentId: args.documentId,\r\n requestBody: {\r\n requests: [{\r\n deleteContentRange: {\r\n range: { startIndex: 1, endIndex: deleteEndIndex }\r\n }\r\n }]\r\n }\r\n });\r\n }\r\n\r\n // Insert new content\r\n await docs.documents.batchUpdate({\r\n documentId: args.documentId,\r\n requestBody: {\r\n requests: [\r\n {\r\n insertText: { location: { index: 1 }, text: args.content }\r\n },\r\n // Ensure the text is formatted as normal text, not as a header\r\n {\r\n updateParagraphStyle: {\r\n range: {\r\n startIndex: 1,\r\n endIndex: args.content.length + 1\r\n },\r\n paragraphStyle: {\r\n namedStyleType: 'NORMAL_TEXT'\r\n },\r\n fields: 'namedStyleType'\r\n }\r\n }\r\n ]\r\n }\r\n });\r\n\r\n return {\r\n content: [{ type: \"text\", text: `Updated Google Doc: ${document.data.title}` }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"createGoogleSheet\": {\r\n const validation = CreateGoogleSheetSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const parentFolderId = await resolveFolderId(args.parentFolderId);\r\n\r\n // Check if spreadsheet already exists\r\n const existingFileId = await checkFileExists(args.name, parentFolderId);\r\n if (existingFileId) {\r\n return errorResponse(\r\n `A spreadsheet named \"${args.name}\" already exists in this location. ` +\r\n `To update it, use updateGoogleSheet with spreadsheetId: ${existingFileId}`\r\n );\r\n }\r\n const sheets = google.sheets({ version: 'v4', auth: authClient });\r\n \r\n // Create spreadsheet with initial sheet\r\n const spreadsheet = await sheets.spreadsheets.create({\r\n requestBody: { \r\n properties: { title: args.name },\r\n sheets: [{\r\n properties: {\r\n sheetId: 0,\r\n title: 'Sheet1',\r\n gridProperties: {\r\n rowCount: Math.max(args.data.length, 1000),\r\n columnCount: Math.max(args.data[0]?.length || 0, 26)\r\n }\r\n }\r\n }]\r\n }\r\n });\r\n\r\n await drive.files.update({\r\n fileId: spreadsheet.data.spreadsheetId || '',\r\n addParents: parentFolderId,\r\n removeParents: 'root',\r\n fields: 'id, name, webViewLink',\r\n supportsAllDrives: true\r\n });\r\n\r\n // Now update with data\r\n await sheets.spreadsheets.values.update({\r\n spreadsheetId: spreadsheet.data.spreadsheetId!,\r\n range: 'Sheet1!A1',\r\n valueInputOption: args.valueInputOption || 'RAW',\r\n requestBody: { values: args.data }\r\n });\r\n\r\n return {\r\n content: [{ type: \"text\", text: `Created Google Sheet: ${args.name}\\nID: ${spreadsheet.data.spreadsheetId}` }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"updateGoogleSheet\": {\r\n const validation = UpdateGoogleSheetSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const sheets = google.sheets({ version: 'v4', auth: authClient });\r\n await sheets.spreadsheets.values.update({\r\n spreadsheetId: args.spreadsheetId,\r\n range: args.range,\r\n valueInputOption: args.valueInputOption || 'RAW',\r\n requestBody: { values: args.data }\r\n });\r\n\r\n return {\r\n content: [{ type: \"text\", text: `Updated Google Sheet range: ${args.range}` }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"getGoogleSheetContent\": {\r\n const validation = GetGoogleSheetContentSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const sheets = google.sheets({ version: 'v4', auth: authClient });\r\n const response = await sheets.spreadsheets.values.get({\r\n spreadsheetId: args.spreadsheetId,\r\n range: args.range\r\n });\r\n\r\n const values = response.data.values || [];\r\n let content = `Content for range ${args.range}:\\n\\n`;\r\n \r\n if (values.length === 0) {\r\n content += \"(empty range)\";\r\n } else {\r\n values.forEach((row, rowIndex) => {\r\n content += `Row ${rowIndex + 1}: ${row.join(', ')}\\n`;\r\n });\r\n }\r\n\r\n return {\r\n content: [{ type: \"text\", text: content }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"formatGoogleSheetCells\": {\r\n const validation = FormatGoogleSheetCellsSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const sheets = google.sheets({ version: 'v4', auth: authClient });\r\n \r\n // Parse the range to get sheet ID and grid range\r\n const rangeData = await sheets.spreadsheets.get({\r\n spreadsheetId: args.spreadsheetId,\r\n ranges: [args.range],\r\n fields: 'sheets(properties(sheetId,title))'\r\n });\r\n\r\n console.error(`[DEBUG] formatGoogleSheetCells - range: ${args.range}`);\r\n console.error(`[DEBUG] rangeData.data:`, JSON.stringify(rangeData.data, null, 2));\r\n \r\n const sheetName = args.range.includes('!') ? args.range.split('!')[0] : 'Sheet1';\r\n console.error(`[DEBUG] Calculated sheetName: \"${sheetName}\"`);\r\n \r\n const sheet = rangeData.data.sheets?.find(s => s.properties?.title === sheetName);\r\n console.error(`[DEBUG] Found sheet:`, sheet ? JSON.stringify(sheet, null, 2) : 'null');\r\n \r\n if (!sheet || sheet.properties?.sheetId === undefined || sheet.properties?.sheetId === null) {\r\n console.error(`[DEBUG] Available sheets:`, rangeData.data.sheets?.map(s => s.properties?.title).join(', '));\r\n return errorResponse(`Sheet \"${sheetName}\" not found`);\r\n }\r\n\r\n // Parse A1 notation to grid range\r\n const a1Range = args.range.includes('!') ? args.range.split('!')[1] : args.range;\r\n const gridRange = convertA1ToGridRange(a1Range, sheet.properties.sheetId!);\r\n\r\n const requests: any[] = [{\r\n repeatCell: {\r\n range: gridRange,\r\n cell: {\r\n userEnteredFormat: {\r\n ...(args.backgroundColor && {\r\n backgroundColor: {\r\n red: args.backgroundColor.red || 0,\r\n green: args.backgroundColor.green || 0,\r\n blue: args.backgroundColor.blue || 0\r\n }\r\n }),\r\n ...(args.horizontalAlignment && { horizontalAlignment: args.horizontalAlignment }),\r\n ...(args.verticalAlignment && { verticalAlignment: args.verticalAlignment }),\r\n ...(args.wrapStrategy && { wrapStrategy: args.wrapStrategy })\r\n }\r\n },\r\n fields: [\r\n args.backgroundColor && 'userEnteredFormat.backgroundColor',\r\n args.horizontalAlignment && 'userEnteredFormat.horizontalAlignment',\r\n args.verticalAlignment && 'userEnteredFormat.verticalAlignment',\r\n args.wrapStrategy && 'userEnteredFormat.wrapStrategy'\r\n ].filter(Boolean).join(',')\r\n }\r\n }];\r\n\r\n await sheets.spreadsheets.batchUpdate({\r\n spreadsheetId: args.spreadsheetId,\r\n requestBody: { requests }\r\n });\r\n\r\n return {\r\n content: [{ type: \"text\", text: `Formatted cells in range ${args.range}` }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"formatGoogleSheetText\": {\r\n const validation = FormatGoogleSheetTextSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const sheets = google.sheets({ version: 'v4', auth: authClient });\r\n \r\n // Get sheet information\r\n const rangeData = await sheets.spreadsheets.get({\r\n spreadsheetId: args.spreadsheetId,\r\n ranges: [args.range],\r\n fields: 'sheets(properties(sheetId,title))'\r\n });\r\n\r\n const sheetName = args.range.includes('!') ? args.range.split('!')[0] : 'Sheet1';\r\n const sheet = rangeData.data.sheets?.find(s => s.properties?.title === sheetName);\r\n if (!sheet || sheet.properties?.sheetId === undefined || sheet.properties?.sheetId === null) {\r\n return errorResponse(`Sheet \"${sheetName}\" not found`);\r\n }\r\n\r\n const a1Range = args.range.includes('!') ? args.range.split('!')[1] : args.range;\r\n const gridRange = convertA1ToGridRange(a1Range, sheet.properties.sheetId!);\r\n\r\n const textFormat: any = {};\r\n const fields: string[] = [];\r\n\r\n if (args.bold !== undefined) {\r\n textFormat.bold = args.bold;\r\n fields.push('bold');\r\n }\r\n if (args.italic !== undefined) {\r\n textFormat.italic = args.italic;\r\n fields.push('italic');\r\n }\r\n if (args.strikethrough !== undefined) {\r\n textFormat.strikethrough = args.strikethrough;\r\n fields.push('strikethrough');\r\n }\r\n if (args.underline !== undefined) {\r\n textFormat.underline = args.underline;\r\n fields.push('underline');\r\n }\r\n if (args.fontSize !== undefined) {\r\n textFormat.fontSize = args.fontSize;\r\n fields.push('fontSize');\r\n }\r\n if (args.fontFamily !== undefined) {\r\n textFormat.fontFamily = args.fontFamily;\r\n fields.push('fontFamily');\r\n }\r\n if (args.foregroundColor) {\r\n textFormat.foregroundColor = {\r\n red: args.foregroundColor.red || 0,\r\n green: args.foregroundColor.green || 0,\r\n blue: args.foregroundColor.blue || 0\r\n };\r\n fields.push('foregroundColor');\r\n }\r\n\r\n const requests = [{\r\n repeatCell: {\r\n range: gridRange,\r\n cell: {\r\n userEnteredFormat: { textFormat }\r\n },\r\n fields: 'userEnteredFormat.textFormat(' + fields.join(',') + ')'\r\n }\r\n }];\r\n\r\n await sheets.spreadsheets.batchUpdate({\r\n spreadsheetId: args.spreadsheetId,\r\n requestBody: { requests }\r\n });\r\n\r\n return {\r\n content: [{ type: \"text\", text: `Applied text formatting to range ${args.range}` }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"formatGoogleSheetNumbers\": {\r\n const validation = FormatGoogleSheetNumbersSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const sheets = google.sheets({ version: 'v4', auth: authClient });\r\n \r\n const rangeData = await sheets.spreadsheets.get({\r\n spreadsheetId: args.spreadsheetId,\r\n ranges: [args.range],\r\n fields: 'sheets(properties(sheetId,title))'\r\n });\r\n\r\n const sheetName = args.range.includes('!') ? args.range.split('!')[0] : 'Sheet1';\r\n const sheet = rangeData.data.sheets?.find(s => s.properties?.title === sheetName);\r\n if (!sheet || sheet.properties?.sheetId === undefined || sheet.properties?.sheetId === null) {\r\n return errorResponse(`Sheet \"${sheetName}\" not found`);\r\n }\r\n\r\n const a1Range = args.range.includes('!') ? args.range.split('!')[1] : args.range;\r\n const gridRange = convertA1ToGridRange(a1Range, sheet.properties.sheetId!);\r\n\r\n const numberFormat: any = {\r\n pattern: args.pattern\r\n };\r\n if (args.type) {\r\n numberFormat.type = args.type;\r\n }\r\n\r\n const requests = [{\r\n repeatCell: {\r\n range: gridRange,\r\n cell: {\r\n userEnteredFormat: { numberFormat }\r\n },\r\n fields: 'userEnteredFormat.numberFormat'\r\n }\r\n }];\r\n\r\n await sheets.spreadsheets.batchUpdate({\r\n spreadsheetId: args.spreadsheetId,\r\n requestBody: { requests }\r\n });\r\n\r\n return {\r\n content: [{ type: \"text\", text: `Applied number formatting to range ${args.range}` }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"setGoogleSheetBorders\": {\r\n const validation = SetGoogleSheetBordersSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const sheets = google.sheets({ version: 'v4', auth: authClient });\r\n \r\n const rangeData = await sheets.spreadsheets.get({\r\n spreadsheetId: args.spreadsheetId,\r\n ranges: [args.range],\r\n fields: 'sheets(properties(sheetId,title))'\r\n });\r\n\r\n const sheetName = args.range.includes('!') ? args.range.split('!')[0] : 'Sheet1';\r\n const sheet = rangeData.data.sheets?.find(s => s.properties?.title === sheetName);\r\n if (!sheet || sheet.properties?.sheetId === undefined || sheet.properties?.sheetId === null) {\r\n return errorResponse(`Sheet \"${sheetName}\" not found`);\r\n }\r\n\r\n const a1Range = args.range.includes('!') ? args.range.split('!')[1] : args.range;\r\n const gridRange = convertA1ToGridRange(a1Range, sheet.properties.sheetId!);\r\n\r\n const border = {\r\n style: args.style,\r\n width: args.width || 1,\r\n color: args.color ? {\r\n red: args.color.red || 0,\r\n green: args.color.green || 0,\r\n blue: args.color.blue || 0\r\n } : undefined\r\n };\r\n\r\n const updateBordersRequest: any = {\r\n updateBorders: {\r\n range: gridRange\r\n }\r\n };\r\n\r\n if (args.top !== false) updateBordersRequest.updateBorders.top = border;\r\n if (args.bottom !== false) updateBordersRequest.updateBorders.bottom = border;\r\n if (args.left !== false) updateBordersRequest.updateBorders.left = border;\r\n if (args.right !== false) updateBordersRequest.updateBorders.right = border;\r\n if (args.innerHorizontal) updateBordersRequest.updateBorders.innerHorizontal = border;\r\n if (args.innerVertical) updateBordersRequest.updateBorders.innerVertical = border;\r\n\r\n await sheets.spreadsheets.batchUpdate({\r\n spreadsheetId: args.spreadsheetId,\r\n requestBody: { requests: [updateBordersRequest] }\r\n });\r\n\r\n return {\r\n content: [{ type: \"text\", text: `Set borders for range ${args.range}` }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"mergeGoogleSheetCells\": {\r\n const validation = MergeGoogleSheetCellsSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const sheets = google.sheets({ version: 'v4', auth: authClient });\r\n \r\n const rangeData = await sheets.spreadsheets.get({\r\n spreadsheetId: args.spreadsheetId,\r\n ranges: [args.range],\r\n fields: 'sheets(properties(sheetId,title))'\r\n });\r\n\r\n const sheetName = args.range.includes('!') ? args.range.split('!')[0] : 'Sheet1';\r\n const sheet = rangeData.data.sheets?.find(s => s.properties?.title === sheetName);\r\n if (!sheet || sheet.properties?.sheetId === undefined || sheet.properties?.sheetId === null) {\r\n return errorResponse(`Sheet \"${sheetName}\" not found`);\r\n }\r\n\r\n const a1Range = args.range.includes('!') ? args.range.split('!')[1] : args.range;\r\n const gridRange = convertA1ToGridRange(a1Range, sheet.properties.sheetId!);\r\n\r\n const requests = [{\r\n mergeCells: {\r\n range: gridRange,\r\n mergeType: args.mergeType\r\n }\r\n }];\r\n\r\n await sheets.spreadsheets.batchUpdate({\r\n spreadsheetId: args.spreadsheetId,\r\n requestBody: { requests }\r\n });\r\n\r\n return {\r\n content: [{ type: \"text\", text: `Merged cells in range ${args.range} with type ${args.mergeType}` }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"addGoogleSheetConditionalFormat\": {\r\n const validation = AddGoogleSheetConditionalFormatSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const sheets = google.sheets({ version: 'v4', auth: authClient });\r\n \r\n const rangeData = await sheets.spreadsheets.get({\r\n spreadsheetId: args.spreadsheetId,\r\n ranges: [args.range],\r\n fields: 'sheets(properties(sheetId,title))'\r\n });\r\n\r\n const sheetName = args.range.includes('!') ? args.range.split('!')[0] : 'Sheet1';\r\n const sheet = rangeData.data.sheets?.find(s => s.properties?.title === sheetName);\r\n if (!sheet || sheet.properties?.sheetId === undefined || sheet.properties?.sheetId === null) {\r\n return errorResponse(`Sheet \"${sheetName}\" not found`);\r\n }\r\n\r\n const a1Range = args.range.includes('!') ? args.range.split('!')[1] : args.range;\r\n const gridRange = convertA1ToGridRange(a1Range, sheet.properties.sheetId!);\r\n\r\n // Build condition based on type\r\n const booleanCondition: any = {};\r\n switch (args.condition.type) {\r\n case 'NUMBER_GREATER':\r\n booleanCondition.type = 'NUMBER_GREATER';\r\n booleanCondition.values = [{ userEnteredValue: args.condition.value }];\r\n break;\r\n case 'NUMBER_LESS':\r\n booleanCondition.type = 'NUMBER_LESS';\r\n booleanCondition.values = [{ userEnteredValue: args.condition.value }];\r\n break;\r\n case 'TEXT_CONTAINS':\r\n booleanCondition.type = 'TEXT_CONTAINS';\r\n booleanCondition.values = [{ userEnteredValue: args.condition.value }];\r\n break;\r\n case 'TEXT_STARTS_WITH':\r\n booleanCondition.type = 'TEXT_STARTS_WITH';\r\n booleanCondition.values = [{ userEnteredValue: args.condition.value }];\r\n break;\r\n case 'TEXT_ENDS_WITH':\r\n booleanCondition.type = 'TEXT_ENDS_WITH';\r\n booleanCondition.values = [{ userEnteredValue: args.condition.value }];\r\n break;\r\n case 'CUSTOM_FORMULA':\r\n booleanCondition.type = 'CUSTOM_FORMULA';\r\n booleanCondition.values = [{ userEnteredValue: args.condition.value }];\r\n break;\r\n }\r\n\r\n const format: any = {};\r\n if (args.format.backgroundColor) {\r\n format.backgroundColor = {\r\n red: args.format.backgroundColor.red || 0,\r\n green: args.format.backgroundColor.green || 0,\r\n blue: args.format.backgroundColor.blue || 0\r\n };\r\n }\r\n if (args.format.textFormat) {\r\n format.textFormat = {};\r\n if (args.format.textFormat.bold !== undefined) {\r\n format.textFormat.bold = args.format.textFormat.bold;\r\n }\r\n if (args.format.textFormat.foregroundColor) {\r\n format.textFormat.foregroundColor = {\r\n red: args.format.textFormat.foregroundColor.red || 0,\r\n green: args.format.textFormat.foregroundColor.green || 0,\r\n blue: args.format.textFormat.foregroundColor.blue || 0\r\n };\r\n }\r\n }\r\n\r\n const requests = [{\r\n addConditionalFormatRule: {\r\n rule: {\r\n ranges: [gridRange],\r\n booleanRule: {\r\n condition: booleanCondition,\r\n format: format\r\n }\r\n },\r\n index: 0\r\n }\r\n }];\r\n\r\n await sheets.spreadsheets.batchUpdate({\r\n spreadsheetId: args.spreadsheetId,\r\n requestBody: { requests }\r\n });\r\n\r\n return {\r\n content: [{ type: \"text\", text: `Added conditional formatting to range ${args.range}` }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"createGoogleSlides\": {\r\n const validation = CreateGoogleSlidesSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const parentFolderId = await resolveFolderId(args.parentFolderId);\r\n\r\n // Check if presentation already exists\r\n const existingFileId = await checkFileExists(args.name, parentFolderId);\r\n if (existingFileId) {\r\n return errorResponse(\r\n `A presentation named \"${args.name}\" already exists in this location. ` +\r\n `File ID: ${existingFileId}. To modify it, you can use Google Slides directly.`\r\n );\r\n }\r\n\r\n const slidesService = google.slides({ version: 'v1', auth: authClient });\r\n const presentation = await slidesService.presentations.create({\r\n requestBody: { title: args.name },\r\n });\r\n\r\n await drive.files.update({\r\n fileId: presentation.data.presentationId!,\r\n addParents: parentFolderId,\r\n removeParents: 'root',\r\n supportsAllDrives: true\r\n });\r\n\r\n for (const slide of args.slides) {\r\n const slideObjectId = `slide_${uuidv4().substring(0, 8)}`;\r\n await slidesService.presentations.batchUpdate({\r\n presentationId: presentation.data.presentationId!,\r\n requestBody: {\r\n requests: [{\r\n createSlide: {\r\n objectId: slideObjectId,\r\n slideLayoutReference: { predefinedLayout: 'TITLE_AND_BODY' },\r\n }\r\n }]\r\n },\r\n });\r\n\r\n const slidePage = await slidesService.presentations.pages.get({\r\n presentationId: presentation.data.presentationId!,\r\n pageObjectId: slideObjectId,\r\n });\r\n\r\n let titlePlaceholderId = '';\r\n let bodyPlaceholderId = '';\r\n slidePage.data.pageElements?.forEach((el) => {\r\n if (el.shape?.placeholder?.type === 'TITLE') {\r\n titlePlaceholderId = el.objectId!;\r\n } else if (el.shape?.placeholder?.type === 'BODY') {\r\n bodyPlaceholderId = el.objectId!;\r\n }\r\n });\r\n\r\n await slidesService.presentations.batchUpdate({\r\n presentationId: presentation.data.presentationId!,\r\n requestBody: {\r\n requests: [\r\n { insertText: { objectId: titlePlaceholderId, text: slide.title, insertionIndex: 0 } },\r\n { insertText: { objectId: bodyPlaceholderId, text: slide.content, insertionIndex: 0 } }\r\n ]\r\n },\r\n });\r\n }\r\n\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `Created Google Slides presentation: ${args.name}\\nID: ${presentation.data.presentationId}\\nLink: https://docs.google.com/presentation/d/${presentation.data.presentationId}`,\r\n }],\r\n isError: false,\r\n };\r\n }\r\n\r\n case \"updateGoogleSlides\": {\r\n const validation = UpdateGoogleSlidesSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const slidesService = google.slides({ version: 'v1', auth: authClient });\r\n \r\n // Get current presentation details\r\n const currentPresentation = await slidesService.presentations.get({\r\n presentationId: args.presentationId\r\n });\r\n \r\n if (!currentPresentation.data.slides) {\r\n return errorResponse(\"No slides found in presentation\");\r\n }\r\n\r\n // Collect all slide IDs except the first one (we'll keep it for now)\r\n const slideIdsToDelete = currentPresentation.data.slides\r\n .slice(1)\r\n .map(slide => slide.objectId)\r\n .filter((id): id is string => id !== undefined);\r\n\r\n // Prepare requests to update presentation\r\n const requests: any[] = [];\r\n\r\n // Delete all slides except the first one\r\n if (slideIdsToDelete.length > 0) {\r\n slideIdsToDelete.forEach(slideId => {\r\n requests.push({\r\n deleteObject: { objectId: slideId }\r\n });\r\n });\r\n }\r\n\r\n // Now we need to update the first slide or create new slides\r\n if (args.slides.length === 0) {\r\n return errorResponse(\"At least one slide must be provided\");\r\n }\r\n\r\n // Clear content of the first slide\r\n const firstSlide = currentPresentation.data.slides[0];\r\n if (firstSlide && firstSlide.pageElements) {\r\n // Find text elements to clear\r\n firstSlide.pageElements.forEach(element => {\r\n if (element.objectId && element.shape?.text) {\r\n requests.push({\r\n deleteText: {\r\n objectId: element.objectId,\r\n textRange: { type: 'ALL' }\r\n }\r\n });\r\n }\r\n });\r\n }\r\n\r\n // Update the first slide with new content\r\n const firstSlideContent = args.slides[0];\r\n if (firstSlide && firstSlide.pageElements) {\r\n // Find title and body placeholders\r\n let titlePlaceholderId: string | undefined;\r\n let bodyPlaceholderId: string | undefined;\r\n\r\n firstSlide.pageElements.forEach(element => {\r\n if (element.shape?.placeholder?.type === 'TITLE' || element.shape?.placeholder?.type === 'CENTERED_TITLE') {\r\n titlePlaceholderId = element.objectId || undefined;\r\n } else if (element.shape?.placeholder?.type === 'BODY' || element.shape?.placeholder?.type === 'SUBTITLE') {\r\n bodyPlaceholderId = element.objectId || undefined;\r\n }\r\n });\r\n\r\n if (titlePlaceholderId) {\r\n requests.push({\r\n insertText: {\r\n objectId: titlePlaceholderId,\r\n text: firstSlideContent.title,\r\n insertionIndex: 0\r\n }\r\n });\r\n }\r\n\r\n if (bodyPlaceholderId) {\r\n requests.push({\r\n insertText: {\r\n objectId: bodyPlaceholderId,\r\n text: firstSlideContent.content,\r\n insertionIndex: 0\r\n }\r\n });\r\n }\r\n }\r\n\r\n // Add any additional slides from the request\r\n for (let i = 1; i < args.slides.length; i++) {\r\n const slide = args.slides[i];\r\n const slideId = `slide_${Date.now()}_${i}`;\r\n \r\n requests.push({\r\n createSlide: {\r\n objectId: slideId,\r\n slideLayoutReference: {\r\n predefinedLayout: 'TITLE_AND_BODY'\r\n }\r\n }\r\n });\r\n\r\n // We'll need to add content to these slides in a separate batch update\r\n // because we need to wait for the slides to be created first\r\n }\r\n\r\n // Execute the batch update\r\n await slidesService.presentations.batchUpdate({\r\n presentationId: args.presentationId,\r\n requestBody: { requests }\r\n });\r\n\r\n // If we have additional slides, add their content\r\n if (args.slides.length > 1) {\r\n const contentRequests: any[] = [];\r\n \r\n // Get updated presentation to find the new slide IDs\r\n const updatedPresentation = await slidesService.presentations.get({\r\n presentationId: args.presentationId\r\n });\r\n\r\n // Add content to the new slides (starting from the second slide in our args)\r\n for (let i = 1; i < args.slides.length && updatedPresentation.data.slides; i++) {\r\n const slide = args.slides[i];\r\n const presentationSlide = updatedPresentation.data.slides[i];\r\n \r\n if (presentationSlide && presentationSlide.pageElements) {\r\n presentationSlide.pageElements.forEach(element => {\r\n if (element.objectId) {\r\n if (element.shape?.placeholder?.type === 'TITLE' || element.shape?.placeholder?.type === 'CENTERED_TITLE') {\r\n contentRequests.push({\r\n insertText: {\r\n objectId: element.objectId,\r\n text: slide.title,\r\n insertionIndex: 0\r\n }\r\n });\r\n } else if (element.shape?.placeholder?.type === 'BODY' || element.shape?.placeholder?.type === 'SUBTITLE') {\r\n contentRequests.push({\r\n insertText: {\r\n objectId: element.objectId,\r\n text: slide.content,\r\n insertionIndex: 0\r\n }\r\n });\r\n }\r\n }\r\n });\r\n }\r\n }\r\n\r\n if (contentRequests.length > 0) {\r\n await slidesService.presentations.batchUpdate({\r\n presentationId: args.presentationId,\r\n requestBody: { requests: contentRequests }\r\n });\r\n }\r\n }\r\n\r\n return {\r\n content: [{\r\n type: 'text',\r\n text: `Updated Google Slides presentation with ${args.slides.length} slide(s)\\nLink: https://docs.google.com/presentation/d/${args.presentationId}`,\r\n }],\r\n isError: false,\r\n };\r\n }\r\n\r\n case \"formatGoogleDocText\": {\r\n const validation = FormatGoogleDocTextSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const docs = google.docs({ version: 'v1', auth: authClient });\r\n \r\n // Build text style object\r\n const textStyle: any = {};\r\n const fields: string[] = [];\r\n \r\n if (args.bold !== undefined) {\r\n textStyle.bold = args.bold;\r\n fields.push('bold');\r\n }\r\n \r\n if (args.italic !== undefined) {\r\n textStyle.italic = args.italic;\r\n fields.push('italic');\r\n }\r\n \r\n if (args.underline !== undefined) {\r\n textStyle.underline = args.underline;\r\n fields.push('underline');\r\n }\r\n \r\n if (args.strikethrough !== undefined) {\r\n textStyle.strikethrough = args.strikethrough;\r\n fields.push('strikethrough');\r\n }\r\n \r\n if (args.fontSize !== undefined) {\r\n textStyle.fontSize = {\r\n magnitude: args.fontSize,\r\n unit: 'PT'\r\n };\r\n fields.push('fontSize');\r\n }\r\n \r\n if (args.foregroundColor) {\r\n textStyle.foregroundColor = {\r\n color: {\r\n rgbColor: {\r\n red: args.foregroundColor.red || 0,\r\n green: args.foregroundColor.green || 0,\r\n blue: args.foregroundColor.blue || 0\r\n }\r\n }\r\n };\r\n fields.push('foregroundColor');\r\n }\r\n \r\n if (fields.length === 0) {\r\n return errorResponse(\"No formatting options specified\");\r\n }\r\n \r\n await docs.documents.batchUpdate({\r\n documentId: args.documentId,\r\n requestBody: {\r\n requests: [{\r\n updateTextStyle: {\r\n range: {\r\n startIndex: args.startIndex,\r\n endIndex: args.endIndex\r\n },\r\n textStyle,\r\n fields: fields.join(',')\r\n }\r\n }]\r\n }\r\n });\r\n \r\n return {\r\n content: [{ type: \"text\", text: `Applied text formatting to range ${args.startIndex}-${args.endIndex}` }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"formatGoogleDocParagraph\": {\r\n const validation = FormatGoogleDocParagraphSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const docs = google.docs({ version: 'v1', auth: authClient });\r\n \r\n // Build paragraph style object\r\n const paragraphStyle: any = {};\r\n const fields: string[] = [];\r\n \r\n if (args.namedStyleType !== undefined) {\r\n paragraphStyle.namedStyleType = args.namedStyleType;\r\n fields.push('namedStyleType');\r\n }\r\n \r\n if (args.alignment !== undefined) {\r\n paragraphStyle.alignment = args.alignment;\r\n fields.push('alignment');\r\n }\r\n \r\n if (args.lineSpacing !== undefined) {\r\n paragraphStyle.lineSpacing = args.lineSpacing;\r\n fields.push('lineSpacing');\r\n }\r\n \r\n if (args.spaceAbove !== undefined) {\r\n paragraphStyle.spaceAbove = {\r\n magnitude: args.spaceAbove,\r\n unit: 'PT'\r\n };\r\n fields.push('spaceAbove');\r\n }\r\n \r\n if (args.spaceBelow !== undefined) {\r\n paragraphStyle.spaceBelow = {\r\n magnitude: args.spaceBelow,\r\n unit: 'PT'\r\n };\r\n fields.push('spaceBelow');\r\n }\r\n \r\n if (fields.length === 0) {\r\n return errorResponse(\"No formatting options specified\");\r\n }\r\n \r\n await docs.documents.batchUpdate({\r\n documentId: args.documentId,\r\n requestBody: {\r\n requests: [{\r\n updateParagraphStyle: {\r\n range: {\r\n startIndex: args.startIndex,\r\n endIndex: args.endIndex\r\n },\r\n paragraphStyle,\r\n fields: fields.join(',')\r\n }\r\n }]\r\n }\r\n });\r\n \r\n return {\r\n content: [{ type: \"text\", text: `Applied paragraph formatting to range ${args.startIndex}-${args.endIndex}` }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"getGoogleDocContent\": {\r\n const validation = GetGoogleDocContentSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const docs = google.docs({ version: 'v1', auth: authClient });\r\n const document = await docs.documents.get({ documentId: args.documentId });\r\n \r\n let content = '';\r\n let currentIndex = 1;\r\n const segments: Array<{text: string, startIndex: number, endIndex: number}> = [];\r\n \r\n // Extract text content with indices\r\n if (document.data.body?.content) {\r\n for (const element of document.data.body.content) {\r\n if (element.paragraph?.elements) {\r\n for (const textElement of element.paragraph.elements) {\r\n if (textElement.textRun?.content) {\r\n const text = textElement.textRun.content;\r\n segments.push({\r\n text,\r\n startIndex: currentIndex,\r\n endIndex: currentIndex + text.length\r\n });\r\n content += text;\r\n currentIndex += text.length;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n \r\n // Format the response to show text with indices\r\n let formattedContent = 'Document content with indices:\\n\\n';\r\n let lineStart = 1;\r\n const lines = content.split('\\n');\r\n \r\n for (let i = 0; i < lines.length; i++) {\r\n const line = lines[i];\r\n const lineEnd = lineStart + line.length;\r\n if (line.trim()) {\r\n formattedContent += `[${lineStart}-${lineEnd}] ${line}\\n`;\r\n }\r\n lineStart = lineEnd + 1; // +1 for the newline character\r\n }\r\n \r\n return {\r\n content: [{\r\n type: \"text\",\r\n text: formattedContent + `\\nTotal length: ${content.length} characters`\r\n }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"getGoogleSlidesContent\": {\r\n const validation = GetGoogleSlidesContentSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const slidesService = google.slides({ version: 'v1', auth: authClient });\r\n const presentation = await slidesService.presentations.get({\r\n presentationId: args.presentationId\r\n });\r\n\r\n if (!presentation.data.slides) {\r\n return errorResponse(\"No slides found in presentation\");\r\n }\r\n\r\n let content = 'Presentation content with element IDs:\\n\\n';\r\n const slides = args.slideIndex !== undefined \r\n ? [presentation.data.slides[args.slideIndex]]\r\n : presentation.data.slides;\r\n\r\n slides.forEach((slide, index) => {\r\n if (!slide || !slide.objectId) return;\r\n \r\n content += `\\nSlide ${args.slideIndex ?? index} (ID: ${slide.objectId}):\\n`;\r\n content += '----------------------------\\n';\r\n\r\n if (slide.pageElements) {\r\n slide.pageElements.forEach((element) => {\r\n if (!element.objectId) return;\r\n\r\n if (element.shape?.text) {\r\n content += ` Text Box (ID: ${element.objectId}):\\n`;\r\n const textElements = element.shape.text.textElements || [];\r\n let text = '';\r\n textElements.forEach((textElement) => {\r\n if (textElement.textRun?.content) {\r\n text += textElement.textRun.content;\r\n }\r\n });\r\n content += ` \"${text.trim()}\"\\n`;\r\n } else if (element.shape) {\r\n content += ` Shape (ID: ${element.objectId}): ${element.shape.shapeType || 'Unknown'}\\n`;\r\n } else if (element.image) {\r\n content += ` Image (ID: ${element.objectId})\\n`;\r\n } else if (element.video) {\r\n content += ` Video (ID: ${element.objectId})\\n`;\r\n } else if (element.table) {\r\n content += ` Table (ID: ${element.objectId})\\n`;\r\n }\r\n });\r\n }\r\n });\r\n\r\n return {\r\n content: [{ type: \"text\", text: content }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"formatGoogleSlidesText\": {\r\n const validation = FormatGoogleSlidesTextSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const slidesService = google.slides({ version: 'v1', auth: authClient });\r\n const textStyle: any = {};\r\n const fields: string[] = [];\r\n\r\n if (args.bold !== undefined) {\r\n textStyle.bold = args.bold;\r\n fields.push('bold');\r\n }\r\n\r\n if (args.italic !== undefined) {\r\n textStyle.italic = args.italic;\r\n fields.push('italic');\r\n }\r\n\r\n if (args.underline !== undefined) {\r\n textStyle.underline = args.underline;\r\n fields.push('underline');\r\n }\r\n\r\n if (args.strikethrough !== undefined) {\r\n textStyle.strikethrough = args.strikethrough;\r\n fields.push('strikethrough');\r\n }\r\n\r\n if (args.fontSize !== undefined) {\r\n textStyle.fontSize = {\r\n magnitude: args.fontSize,\r\n unit: 'PT'\r\n };\r\n fields.push('fontSize');\r\n }\r\n\r\n if (args.fontFamily !== undefined) {\r\n textStyle.fontFamily = args.fontFamily;\r\n fields.push('fontFamily');\r\n }\r\n\r\n if (args.foregroundColor) {\r\n textStyle.foregroundColor = {\r\n opaqueColor: {\r\n rgbColor: {\r\n red: args.foregroundColor.red || 0,\r\n green: args.foregroundColor.green || 0,\r\n blue: args.foregroundColor.blue || 0\r\n }\r\n }\r\n };\r\n fields.push('foregroundColor');\r\n }\r\n\r\n if (fields.length === 0) {\r\n return errorResponse(\"No formatting options specified\");\r\n }\r\n\r\n const updateRequest: any = {\r\n updateTextStyle: {\r\n objectId: args.objectId,\r\n style: textStyle,\r\n fields: fields.join(',')\r\n }\r\n };\r\n\r\n // Add text range if specified\r\n if (args.startIndex !== undefined && args.endIndex !== undefined) {\r\n updateRequest.updateTextStyle.textRange = {\r\n type: 'FIXED_RANGE',\r\n startIndex: args.startIndex,\r\n endIndex: args.endIndex\r\n };\r\n } else {\r\n updateRequest.updateTextStyle.textRange = { type: 'ALL' };\r\n }\r\n\r\n await slidesService.presentations.batchUpdate({\r\n presentationId: args.presentationId,\r\n requestBody: { requests: [updateRequest] }\r\n });\r\n\r\n return {\r\n content: [{ type: \"text\", text: `Applied text formatting to object ${args.objectId}` }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"formatGoogleSlidesParagraph\": {\r\n const validation = FormatGoogleSlidesParagraphSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const slidesService = google.slides({ version: 'v1', auth: authClient });\r\n const requests: any[] = [];\r\n\r\n if (args.alignment) {\r\n requests.push({\r\n updateParagraphStyle: {\r\n objectId: args.objectId,\r\n style: { alignment: args.alignment },\r\n fields: 'alignment'\r\n }\r\n });\r\n }\r\n\r\n if (args.lineSpacing !== undefined) {\r\n requests.push({\r\n updateParagraphStyle: {\r\n objectId: args.objectId,\r\n style: { lineSpacing: args.lineSpacing },\r\n fields: 'lineSpacing'\r\n }\r\n });\r\n }\r\n\r\n if (args.bulletStyle) {\r\n if (args.bulletStyle === 'NONE') {\r\n requests.push({\r\n deleteParagraphBullets: {\r\n objectId: args.objectId\r\n }\r\n });\r\n } else if (args.bulletStyle === 'NUMBERED') {\r\n requests.push({\r\n createParagraphBullets: {\r\n objectId: args.objectId,\r\n bulletPreset: 'NUMBERED_DIGIT_ALPHA_ROMAN'\r\n }\r\n });\r\n } else {\r\n requests.push({\r\n createParagraphBullets: {\r\n objectId: args.objectId,\r\n bulletPreset: `BULLET_${args.bulletStyle}_CIRCLE_SQUARE`\r\n }\r\n });\r\n }\r\n }\r\n\r\n if (requests.length === 0) {\r\n return errorResponse(\"No formatting options specified\");\r\n }\r\n\r\n await slidesService.presentations.batchUpdate({\r\n presentationId: args.presentationId,\r\n requestBody: { requests }\r\n });\r\n\r\n return {\r\n content: [{ type: \"text\", text: `Applied paragraph formatting to object ${args.objectId}` }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"styleGoogleSlidesShape\": {\r\n const validation = StyleGoogleSlidesShapeSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const slidesService = google.slides({ version: 'v1', auth: authClient });\r\n const shapeProperties: any = {};\r\n const fields: string[] = [];\r\n\r\n if (args.backgroundColor) {\r\n shapeProperties.shapeBackgroundFill = {\r\n solidFill: {\r\n color: {\r\n rgbColor: {\r\n red: args.backgroundColor.red || 0,\r\n green: args.backgroundColor.green || 0,\r\n blue: args.backgroundColor.blue || 0\r\n }\r\n },\r\n alpha: args.backgroundColor.alpha || 1\r\n }\r\n };\r\n fields.push('shapeBackgroundFill');\r\n }\r\n\r\n const outline: any = {};\r\n let hasOutlineChanges = false;\r\n\r\n if (args.outlineColor) {\r\n outline.outlineFill = {\r\n solidFill: {\r\n color: {\r\n rgbColor: {\r\n red: args.outlineColor.red || 0,\r\n green: args.outlineColor.green || 0,\r\n blue: args.outlineColor.blue || 0\r\n }\r\n }\r\n }\r\n };\r\n hasOutlineChanges = true;\r\n }\r\n\r\n if (args.outlineWeight !== undefined) {\r\n outline.weight = {\r\n magnitude: args.outlineWeight,\r\n unit: 'PT'\r\n };\r\n hasOutlineChanges = true;\r\n }\r\n\r\n if (args.outlineDashStyle !== undefined) {\r\n outline.dashStyle = args.outlineDashStyle;\r\n hasOutlineChanges = true;\r\n }\r\n\r\n if (hasOutlineChanges) {\r\n shapeProperties.outline = outline;\r\n fields.push('outline');\r\n }\r\n\r\n if (fields.length === 0) {\r\n return errorResponse(\"No styling options specified\");\r\n }\r\n\r\n await slidesService.presentations.batchUpdate({\r\n presentationId: args.presentationId,\r\n requestBody: {\r\n requests: [{\r\n updateShapeProperties: {\r\n objectId: args.objectId,\r\n shapeProperties,\r\n fields: fields.join(',')\r\n }\r\n }]\r\n }\r\n });\r\n\r\n return {\r\n content: [{ type: \"text\", text: `Applied styling to shape ${args.objectId}` }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"setGoogleSlidesBackground\": {\r\n const validation = SetGoogleSlidesBackgroundSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const slidesService = google.slides({ version: 'v1', auth: authClient });\r\n const requests = args.pageObjectIds.map(pageObjectId => ({\r\n updatePageProperties: {\r\n objectId: pageObjectId,\r\n pageProperties: {\r\n pageBackgroundFill: {\r\n solidFill: {\r\n color: {\r\n rgbColor: {\r\n red: args.backgroundColor.red || 0,\r\n green: args.backgroundColor.green || 0,\r\n blue: args.backgroundColor.blue || 0\r\n }\r\n },\r\n alpha: args.backgroundColor.alpha || 1\r\n }\r\n }\r\n },\r\n fields: 'pageBackgroundFill'\r\n }\r\n }));\r\n\r\n await slidesService.presentations.batchUpdate({\r\n presentationId: args.presentationId,\r\n requestBody: { requests }\r\n });\r\n\r\n return {\r\n content: [{ type: \"text\", text: `Set background color for ${args.pageObjectIds.length} slide(s)` }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"createGoogleSlidesTextBox\": {\r\n const validation = CreateGoogleSlidesTextBoxSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const slidesService = google.slides({ version: 'v1', auth: authClient });\r\n const elementId = `textBox_${uuidv4().substring(0, 8)}`;\r\n\r\n const requests: any[] = [\r\n {\r\n createShape: {\r\n objectId: elementId,\r\n shapeType: 'TEXT_BOX',\r\n elementProperties: {\r\n pageObjectId: args.pageObjectId,\r\n size: {\r\n width: { magnitude: args.width, unit: 'EMU' },\r\n height: { magnitude: args.height, unit: 'EMU' }\r\n },\r\n transform: {\r\n scaleX: 1,\r\n scaleY: 1,\r\n translateX: args.x,\r\n translateY: args.y,\r\n unit: 'EMU'\r\n }\r\n }\r\n }\r\n },\r\n {\r\n insertText: {\r\n objectId: elementId,\r\n text: args.text,\r\n insertionIndex: 0\r\n }\r\n }\r\n ];\r\n\r\n // Apply optional formatting\r\n if (args.fontSize || args.bold || args.italic) {\r\n const textStyle: any = {};\r\n const fields: string[] = [];\r\n\r\n if (args.fontSize) {\r\n textStyle.fontSize = {\r\n magnitude: args.fontSize,\r\n unit: 'PT'\r\n };\r\n fields.push('fontSize');\r\n }\r\n\r\n if (args.bold !== undefined) {\r\n textStyle.bold = args.bold;\r\n fields.push('bold');\r\n }\r\n\r\n if (args.italic !== undefined) {\r\n textStyle.italic = args.italic;\r\n fields.push('italic');\r\n }\r\n\r\n if (fields.length > 0) {\r\n requests.push({\r\n updateTextStyle: {\r\n objectId: elementId,\r\n style: textStyle,\r\n fields: fields.join(','),\r\n textRange: { type: 'ALL' }\r\n }\r\n });\r\n }\r\n }\r\n\r\n await slidesService.presentations.batchUpdate({\r\n presentationId: args.presentationId,\r\n requestBody: { requests }\r\n });\r\n\r\n return {\r\n content: [{ type: \"text\", text: `Created text box with ID: ${elementId}` }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"createGoogleSlidesShape\": {\r\n const validation = CreateGoogleSlidesShapeSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const slidesService = google.slides({ version: 'v1', auth: authClient });\r\n const elementId = `shape_${uuidv4().substring(0, 8)}`;\r\n\r\n const createRequest: any = {\r\n createShape: {\r\n objectId: elementId,\r\n shapeType: args.shapeType,\r\n elementProperties: {\r\n pageObjectId: args.pageObjectId,\r\n size: {\r\n width: { magnitude: args.width, unit: 'EMU' },\r\n height: { magnitude: args.height, unit: 'EMU' }\r\n },\r\n transform: {\r\n scaleX: 1,\r\n scaleY: 1,\r\n translateX: args.x,\r\n translateY: args.y,\r\n unit: 'EMU'\r\n }\r\n }\r\n }\r\n };\r\n\r\n const requests = [createRequest];\r\n\r\n // Apply background color if specified\r\n if (args.backgroundColor) {\r\n requests.push({\r\n updateShapeProperties: {\r\n objectId: elementId,\r\n shapeProperties: {\r\n shapeBackgroundFill: {\r\n solidFill: {\r\n color: {\r\n rgbColor: {\r\n red: args.backgroundColor.red || 0,\r\n green: args.backgroundColor.green || 0,\r\n blue: args.backgroundColor.blue || 0\r\n }\r\n },\r\n alpha: args.backgroundColor.alpha || 1\r\n }\r\n }\r\n },\r\n fields: 'shapeBackgroundFill'\r\n }\r\n });\r\n }\r\n\r\n await slidesService.presentations.batchUpdate({\r\n presentationId: args.presentationId,\r\n requestBody: { requests }\r\n });\r\n\r\n return {\r\n content: [{ type: \"text\", text: `Created ${args.shapeType} shape with ID: ${elementId}` }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"getGoogleSlidesSpeakerNotes\": {\r\n const validation = GetGoogleSlidesSpeakerNotesSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const slidesService = google.slides({ version: 'v1', auth: authClient });\r\n\r\n // Get the presentation to access the slide\r\n const presentation = await slidesService.presentations.get({\r\n presentationId: args.presentationId\r\n });\r\n\r\n if (!presentation.data.slides || args.slideIndex >= presentation.data.slides.length) {\r\n return errorResponse(`Slide index ${args.slideIndex} not found in presentation (has ${presentation.data.slides?.length ?? 0} slides)`);\r\n }\r\n\r\n const slide = presentation.data.slides[args.slideIndex];\r\n\r\n // Get the notes page object ID from the slide properties\r\n const notesObjectId = slide.slideProperties?.notesPage?.notesProperties?.speakerNotesObjectId;\r\n\r\n if (!notesObjectId) {\r\n return {\r\n content: [{ type: \"text\", text: \"No speaker notes found for this slide\" }],\r\n isError: false\r\n };\r\n }\r\n\r\n // Get the notes page to read the speaker notes text\r\n const notesPageObjectId = slide.slideProperties?.notesPage?.objectId;\r\n if (!notesPageObjectId) {\r\n return {\r\n content: [{ type: \"text\", text: \"No speaker notes found for this slide\" }],\r\n isError: false\r\n };\r\n }\r\n\r\n // Find the notes page for this slide\r\n const notesPage = presentation.data.slides?.[args.slideIndex]?.slideProperties?.notesPage;\r\n\r\n if (!notesPage || !notesPage.pageElements) {\r\n return {\r\n content: [{ type: \"text\", text: \"No speaker notes found for this slide\" }],\r\n isError: false\r\n };\r\n }\r\n\r\n // Find the speaker notes shape\r\n const speakerNotesElement = notesPage.pageElements.find(\r\n element => element.objectId === notesObjectId\r\n );\r\n\r\n if (!speakerNotesElement || !speakerNotesElement.shape?.text) {\r\n return {\r\n content: [{ type: \"text\", text: \"No speaker notes found for this slide\" }],\r\n isError: false\r\n };\r\n }\r\n\r\n // Extract the text from the speaker notes\r\n let notesText = '';\r\n const textElements = speakerNotesElement.shape.text.textElements || [];\r\n textElements.forEach((textElement) => {\r\n if (textElement.textRun?.content) {\r\n notesText += textElement.textRun.content;\r\n }\r\n });\r\n\r\n return {\r\n content: [{ type: \"text\", text: notesText.trim() || \"No speaker notes found for this slide\" }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"updateGoogleSlidesSpeakerNotes\": {\r\n const validation = UpdateGoogleSlidesSpeakerNotesSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n const slidesService = google.slides({ version: 'v1', auth: authClient });\r\n\r\n // Get the presentation to access the slide\r\n const presentation = await slidesService.presentations.get({\r\n presentationId: args.presentationId\r\n });\r\n\r\n if (!presentation.data.slides || args.slideIndex >= presentation.data.slides.length) {\r\n return errorResponse(`Slide index ${args.slideIndex} not found in presentation (has ${presentation.data.slides?.length ?? 0} slides)`);\r\n }\r\n\r\n const slide = presentation.data.slides[args.slideIndex];\r\n\r\n // Get the notes page object ID from the slide properties\r\n const notesObjectId = slide.slideProperties?.notesPage?.notesProperties?.speakerNotesObjectId;\r\n\r\n if (!notesObjectId) {\r\n return errorResponse(\"This slide does not have a speaker notes object. Speaker notes may need to be initialized manually in Google Slides first.\");\r\n }\r\n\r\n // Create the batchUpdate request to replace the speaker notes text\r\n const requests = [\r\n {\r\n deleteText: {\r\n objectId: notesObjectId,\r\n textRange: {\r\n type: 'ALL'\r\n }\r\n }\r\n },\r\n {\r\n insertText: {\r\n objectId: notesObjectId,\r\n text: args.notes,\r\n insertionIndex: 0\r\n }\r\n }\r\n ];\r\n\r\n await slidesService.presentations.batchUpdate({\r\n presentationId: args.presentationId,\r\n requestBody: { requests }\r\n });\r\n\r\n return {\r\n content: [{ type: \"text\", text: `Successfully updated speaker notes for slide ${args.slideIndex}` }],\r\n isError: false\r\n };\r\n }\r\n\r\n case \"uploadFile\": {\r\n const validation = UploadFileSchema.safeParse(request.params.arguments);\r\n if (!validation.success) {\r\n return errorResponse(validation.error.errors[0].message);\r\n }\r\n const args = validation.data;\r\n\r\n // Validate local file exists\r\n if (!existsSync(args.localPath)) {\r\n return errorResponse(`File not found: ${args.localPath}`);\r\n }\r\n\r\n const stats = statSync(args.localPath);\r\n const fileName = args.name || args.localPath.split(/[\\\\/]/).pop() || 'upload';\r\n const ext = fileName.split('.').pop()?.toLowerCase() || '';\r\n const detectedMime = args.mimeType || BINARY_MIME_TYPES[ext] || 'application/octet-stream';\r\n const parentId = await resolveFolderId(args.parentFolderId);\r\n\r\n log('Uploading file', { localPath: args.localPath, name: fileName, mimeType: detectedMime, size: stats.size });\r\n\r\n const file = await drive.files.create({\r\n requestBody: {\r\n name: fileName,\r\n parents: [parentId]\r\n },\r\n media: {\r\n mimeType: detectedMime,\r\n body: createReadStream(args.localPath)\r\n },\r\n fields: 'id, name, size, mimeType, webViewLink',\r\n supportsAllDrives: true\r\n });\r\n\r\n log('File uploaded successfully', { fileId: file.data?.id });\r\n return {\r\n content: [{\r\n type: \"text\",\r\n text: [\r\n `Uploaded: ${file.data?.name || fileName}`,\r\n `ID: ${file.data?.id || 'unknown'}`,\r\n `Size: ${file.data?.size || stats.size} bytes`,\r\n `Type: ${file.data?.mimeType || detectedMime}`,\r\n file.data?.webViewLink ? `Link: ${file.data.webViewLink}` : ''\r\n ].filter(Boolean).join('\\n')\r\n }],\r\n isError: false\r\n };\r\n }\r\n\r\n default:\r\n return errorResponse(\"Tool not found\");\r\n }\r\n } catch (error) {\r\n log('Error in tool request handler', { error: (error as Error).message });\r\n return errorResponse((error as Error).message);\r\n }\r\n});\r\n\r\n// -----------------------------------------------------------------------------\r\n// CLI FUNCTIONS\r\n// -----------------------------------------------------------------------------\r\n\r\nfunction showHelp(): void {\r\n console.log(`\r\nGoogle Drive MCP Server v${VERSION}\r\n\r\nUsage:\r\n npx @yourusername/google-drive-mcp [command]\r\n\r\nCommands:\r\n auth Run the authentication flow\r\n start Start the MCP server (default)\r\n version Show version information\r\n help Show this help message\r\n\r\nExamples:\r\n npx @yourusername/google-drive-mcp auth\r\n npx @yourusername/google-drive-mcp start\r\n npx @yourusername/google-drive-mcp version\r\n npx @yourusername/google-drive-mcp\r\n\r\nEnvironment Variables:\r\n GOOGLE_DRIVE_OAUTH_CREDENTIALS Path to OAuth credentials file\r\n GOOGLE_DRIVE_MCP_TOKEN_PATH Path to store authentication tokens\r\n`);\r\n}\r\n\r\nfunction showVersion(): void {\r\n console.log(`Google Drive MCP Server v${VERSION}`);\r\n}\r\n\r\nasync function runAuthServer(): Promise<void> {\r\n try {\r\n // Initialize OAuth client\r\n const oauth2Client = await initializeOAuth2Client();\r\n\r\n // Create and start the auth server\r\n const authServerInstance = new AuthServer(oauth2Client);\r\n\r\n // Start with browser opening (true by default)\r\n const success = await authServerInstance.start(true);\r\n\r\n if (!success && !authServerInstance.authCompletedSuccessfully) {\r\n // Failed to start and tokens weren't already valid\r\n console.error(\r\n \"Authentication failed. Could not start server or validate existing tokens. Check port availability (3000-3004) and try again.\"\r\n );\r\n process.exit(1);\r\n } else if (authServerInstance.authCompletedSuccessfully) {\r\n // Auth was successful (either existing tokens were valid or flow completed just now)\r\n console.log(\"Authentication successful.\");\r\n process.exit(0); // Exit cleanly if auth is already done\r\n }\r\n\r\n // If we reach here, the server started and is waiting for the browser callback\r\n console.log(\r\n \"Authentication server started. Please complete the authentication in your browser...\"\r\n );\r\n\r\n // Wait for completion\r\n const intervalId = setInterval(async () => {\r\n if (authServerInstance.authCompletedSuccessfully) {\r\n clearInterval(intervalId);\r\n await authServerInstance.stop();\r\n console.log(\"Authentication completed successfully!\");\r\n process.exit(0);\r\n }\r\n }, 1000);\r\n } catch (error) {\r\n console.error(\"Authentication failed:\", error);\r\n process.exit(1);\r\n }\r\n}\r\n\r\n// -----------------------------------------------------------------------------\r\n// MAIN EXECUTION\r\n// -----------------------------------------------------------------------------\r\n\r\nfunction parseCliArgs(): { command: string | undefined } {\r\n const args = process.argv.slice(2);\r\n let command: string | undefined;\r\n\r\n for (let i = 0; i < args.length; i++) {\r\n const arg = args[i];\r\n \r\n // Handle special version/help flags as commands\r\n if (arg === '--version' || arg === '-v' || arg === '--help' || arg === '-h') {\r\n command = arg;\r\n continue;\r\n }\r\n \r\n // Check for command (first non-option argument)\r\n if (!command && !arg.startsWith('--')) {\r\n command = arg;\r\n continue;\r\n }\r\n }\r\n\r\n return { command };\r\n}\r\n\r\nasync function main() {\r\n const { command } = parseCliArgs();\r\n\r\n switch (command) {\r\n case \"auth\":\r\n await runAuthServer();\r\n break;\r\n case \"start\":\r\n case undefined:\r\n try {\r\n // Start the MCP server\r\n console.error(\"Starting Google Drive MCP server...\");\r\n const transport = new StdioServerTransport();\r\n await server.connect(transport);\r\n log('Server started successfully');\r\n \r\n // Set up graceful shutdown\r\n process.on(\"SIGINT\", async () => {\r\n await server.close();\r\n process.exit(0);\r\n });\r\n process.on(\"SIGTERM\", async () => {\r\n await server.close();\r\n process.exit(0);\r\n });\r\n } catch (error) {\r\n console.error('Failed to start server:', error);\r\n process.exit(1);\r\n }\r\n break;\r\n case \"version\":\r\n case \"--version\":\r\n case \"-v\":\r\n showVersion();\r\n break;\r\n case \"help\":\r\n case \"--help\":\r\n case \"-h\":\r\n showHelp();\r\n break;\r\n default:\r\n console.error(`Unknown command: ${command}`);\r\n showHelp();\r\n process.exit(1);\r\n }\r\n}\r\n\r\n// Export server and main for testing or potential programmatic use\r\nexport { main, server };\r\n\r\n// Run the CLI\r\nmain().catch((error) => {\r\n console.error(\"Fatal error:\", error);\r\n process.exit(1);\r\n});", "import { OAuth2Client } from 'google-auth-library';\r\nimport * as fs from 'fs/promises';\r\nimport { getKeysFilePath, generateCredentialsErrorMessage, OAuthCredentials } from './utils.js';\r\n\r\nasync function loadCredentialsFromFile(): Promise<OAuthCredentials> {\r\n const keysContent = await fs.readFile(getKeysFilePath(), \"utf-8\");\r\n const keys = JSON.parse(keysContent);\r\n\r\n if (keys.installed) {\r\n // Standard OAuth credentials file format\r\n const { client_id, client_secret, redirect_uris } = keys.installed;\r\n return { client_id, client_secret, redirect_uris };\r\n } else if (keys.web) {\r\n // Web application credentials format\r\n const { client_id, client_secret, redirect_uris } = keys.web;\r\n return { client_id, client_secret, redirect_uris };\r\n } else if (keys.client_id) {\r\n // Direct format (simplified)\r\n return {\r\n client_id: keys.client_id,\r\n client_secret: keys.client_secret,\r\n redirect_uris: keys.redirect_uris || ['http://localhost:3000/oauth2callback']\r\n };\r\n } else {\r\n throw new Error('Invalid credentials file format. Expected either \"installed\", \"web\" object or direct client_id field.');\r\n }\r\n}\r\n\r\nasync function loadCredentialsWithFallback(): Promise<OAuthCredentials> {\r\n try {\r\n return await loadCredentialsFromFile();\r\n } catch (fileError) {\r\n // Check for legacy client_secret.json\r\n const legacyPath = process.env.GOOGLE_CLIENT_SECRET_PATH || 'client_secret.json';\r\n try {\r\n const legacyContent = await fs.readFile(legacyPath, 'utf-8');\r\n const legacyKeys = JSON.parse(legacyContent);\r\n console.error('Warning: Using legacy client_secret.json. Please migrate to gcp-oauth.keys.json');\r\n \r\n if (legacyKeys.installed) {\r\n return legacyKeys.installed;\r\n } else if (legacyKeys.web) {\r\n return legacyKeys.web;\r\n } else {\r\n throw new Error('Invalid legacy credentials format');\r\n }\r\n } catch (legacyError) {\r\n // Generate helpful error message\r\n const errorMessage = generateCredentialsErrorMessage();\r\n throw new Error(`${errorMessage}\\n\\nOriginal error: ${fileError instanceof Error ? fileError.message : fileError}`);\r\n }\r\n }\r\n}\r\n\r\nexport async function initializeOAuth2Client(): Promise<OAuth2Client> {\r\n try {\r\n const credentials = await loadCredentialsWithFallback();\r\n \r\n // Use the first redirect URI as the default for the base client\r\n return new OAuth2Client({\r\n clientId: credentials.client_id,\r\n clientSecret: credentials.client_secret || undefined,\r\n redirectUri: credentials.redirect_uris?.[0] || 'http://localhost:3000/oauth2callback',\r\n });\r\n } catch (error) {\r\n throw new Error(`Error loading OAuth keys: ${error instanceof Error ? error.message : error}`);\r\n }\r\n}\r\n\r\nexport async function loadCredentials(): Promise<{ client_id: string; client_secret?: string }> {\r\n try {\r\n const credentials = await loadCredentialsWithFallback();\r\n \r\n if (!credentials.client_id) {\r\n throw new Error('Client ID missing in credentials.');\r\n }\r\n return {\r\n client_id: credentials.client_id,\r\n client_secret: credentials.client_secret\r\n };\r\n } catch (error) {\r\n throw new Error(`Error loading credentials: ${error instanceof Error ? error.message : error}`);\r\n }\r\n}", "import * as path from 'path';\r\nimport * as os from 'os';\r\nimport { fileURLToPath } from 'url';\r\n\r\n// Helper to get the project root directory reliably\r\nfunction getProjectRoot(): string {\r\n const __dirname = path.dirname(fileURLToPath(import.meta.url));\r\n // In build output (e.g., dist/auth/utils.js), __dirname is .../dist/auth\r\n // Go up TWO levels to get the project root\r\n const projectRoot = path.join(__dirname, \"..\", \"..\");\r\n return path.resolve(projectRoot);\r\n}\r\n\r\n// Returns the absolute path for the saved token file.\r\n// Uses XDG Base Directory spec with fallback to home directory\r\nexport function getSecureTokenPath(): string {\r\n // Check for custom token path environment variable first\r\n const customTokenPath = process.env.GOOGLE_DRIVE_MCP_TOKEN_PATH;\r\n if (customTokenPath) {\r\n return path.resolve(customTokenPath);\r\n }\r\n\r\n // Use XDG Base Directory spec or fallback to ~/.config\r\n const configHome = process.env.XDG_CONFIG_HOME || \r\n path.join(os.homedir(), '.config');\r\n \r\n const tokenDir = path.join(configHome, 'google-drive-mcp');\r\n return path.join(tokenDir, 'tokens.json');\r\n}\r\n\r\n// Returns the legacy token path for backward compatibility\r\nexport function getLegacyTokenPath(): string {\r\n const projectRoot = getProjectRoot();\r\n return path.join(projectRoot, \".gcp-saved-tokens.json\");\r\n}\r\n\r\n// Additional legacy paths to check\r\nexport function getAdditionalLegacyPaths(): string[] {\r\n return [\r\n process.env.GOOGLE_TOKEN_PATH,\r\n path.join(process.cwd(), 'google-tokens.json'),\r\n path.join(process.cwd(), '.gcp-saved-tokens.json')\r\n ].filter(Boolean) as string[];\r\n}\r\n\r\n// Returns the absolute path for the GCP OAuth keys file with priority:\r\n// 1. Environment variable GOOGLE_DRIVE_OAUTH_CREDENTIALS (highest priority)\r\n// 2. Default file path (lowest priority)\r\nexport function getKeysFilePath(): string {\r\n // Priority 1: Environment variable\r\n const envCredentialsPath = process.env.GOOGLE_DRIVE_OAUTH_CREDENTIALS;\r\n if (envCredentialsPath) {\r\n return path.resolve(envCredentialsPath);\r\n }\r\n \r\n // Priority 2: Default file path\r\n const projectRoot = getProjectRoot();\r\n const keysPath = path.join(projectRoot, \"gcp-oauth.keys.json\");\r\n return keysPath;\r\n}\r\n\r\n// Interface for OAuth credentials\r\nexport interface OAuthCredentials {\r\n client_id: string;\r\n client_secret?: string;\r\n redirect_uris?: string[];\r\n}\r\n\r\n// Generate helpful error message for missing credentials\r\nexport function generateCredentialsErrorMessage(): string {\r\n return `\r\nOAuth credentials not found. Please provide credentials using one of these methods:\r\n\r\n1. Environment variable:\r\n Set GOOGLE_DRIVE_OAUTH_CREDENTIALS to the path of your credentials file:\r\n export GOOGLE_DRIVE_OAUTH_CREDENTIALS=\"/path/to/gcp-oauth.keys.json\"\r\n\r\n2. Default file path:\r\n Place your gcp-oauth.keys.json file in the package root directory.\r\n\r\nToken storage:\r\n- Tokens are saved to: ${getSecureTokenPath()}\r\n- To use a custom token location, set GOOGLE_DRIVE_MCP_TOKEN_PATH environment variable\r\n\r\nTo get OAuth credentials:\r\n1. Go to the Google Cloud Console (https://console.cloud.google.com/)\r\n2. Create or select a project\r\n3. Enable the Google Drive, Docs, Sheets, and Slides APIs\r\n4. Create OAuth 2.0 credentials (Desktop app type)\r\n5. Download the credentials file as gcp-oauth.keys.json\r\n`.trim();\r\n}", "import express from 'express';\r\nimport { OAuth2Client } from 'google-auth-library';\r\nimport { TokenManager } from './tokenManager.js';\r\nimport http from 'http';\r\nimport open from 'open';\r\nimport { loadCredentials } from './client.js';\r\n\r\n// OAuth scopes for Google Drive, Docs, Sheets, and Slides\r\nconst SCOPES = [\r\n 'https://www.googleapis.com/auth/drive',\r\n 'https://www.googleapis.com/auth/drive.file',\r\n 'https://www.googleapis.com/auth/drive.readonly',\r\n 'https://www.googleapis.com/auth/documents',\r\n 'https://www.googleapis.com/auth/spreadsheets',\r\n 'https://www.googleapis.com/auth/presentations'\r\n];\r\n\r\nexport class AuthServer {\r\n private baseOAuth2Client: OAuth2Client; // Used by TokenManager for validation/refresh\r\n private flowOAuth2Client: OAuth2Client | null = null; // Used specifically for the auth code flow\r\n private app: express.Express;\r\n private server: http.Server | null = null;\r\n private tokenManager: TokenManager;\r\n private portRange: { start: number; end: number };\r\n public authCompletedSuccessfully = false; // Flag for standalone script\r\n\r\n constructor(oauth2Client: OAuth2Client) {\r\n this.baseOAuth2Client = oauth2Client;\r\n this.tokenManager = new TokenManager(oauth2Client);\r\n this.app = express();\r\n this.portRange = { start: 3000, end: 3004 };\r\n this.setupRoutes();\r\n }\r\n\r\n private setupRoutes(): void {\r\n this.app.get('/', (req, res) => {\r\n // Generate the URL using the active flow client if available, else base\r\n const clientForUrl = this.flowOAuth2Client || this.baseOAuth2Client;\r\n const authUrl = clientForUrl.generateAuthUrl({\r\n access_type: 'offline',\r\n scope: SCOPES,\r\n prompt: 'consent'\r\n });\r\n res.send(`<h1>Google Drive Authentication</h1><a href=\"${authUrl}\">Authenticate with Google</a>`);\r\n });\r\n\r\n this.app.get('/oauth2callback', async (req, res) => {\r\n const code = req.query.code as string;\r\n if (!code) {\r\n res.status(400).send('Authorization code missing');\r\n return;\r\n }\r\n // IMPORTANT: Use the flowOAuth2Client to exchange the code\r\n if (!this.flowOAuth2Client) {\r\n res.status(500).send('Authentication flow not properly initiated.');\r\n return;\r\n }\r\n try {\r\n const { tokens } = await this.flowOAuth2Client.getToken(code);\r\n // Save tokens using the TokenManager (which uses the base client)\r\n await this.tokenManager.saveTokens(tokens);\r\n this.authCompletedSuccessfully = true;\r\n\r\n // Get the path where tokens were saved\r\n const tokenPath = this.tokenManager.getTokenPath();\r\n\r\n // Send a more informative HTML response including the path\r\n res.send(`\r\n <!DOCTYPE html>\r\n <html lang=\"en\">\r\n <head>\r\n <meta charset=\"UTF-8\">\r\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n <title>Authentication Successful</title>\r\n <style>\r\n body { font-family: sans-serif; display: flex; justify-content: center; align-items: center; height: 100vh; background-color: #f4f4f4; margin: 0; }\r\n .container { text-align: center; padding: 2em; background-color: #fff; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }\r\n h1 { color: #4CAF50; }\r\n p { color: #333; margin-bottom: 0.5em; }\r\n code { background-color: #eee; padding: 0.2em 0.4em; border-radius: 3px; font-size: 0.9em; }\r\n </style>\r\n </head>\r\n <body>\r\n <div class=\"container\">\r\n <h1>Authentication Successful!</h1>\r\n <p>Your authentication tokens have been saved successfully to:</p>\r\n <p><code>${tokenPath}</code></p>\r\n <p>You can now close this browser window.</p>\r\n </div>\r\n </body>\r\n </html>\r\n `);\r\n } catch (error: unknown) {\r\n this.authCompletedSuccessfully = false;\r\n const message = error instanceof Error ? error.message : 'Unknown error';\r\n // Send an HTML error response\r\n res.status(500).send(`\r\n <!DOCTYPE html>\r\n <html lang=\"en\">\r\n <head>\r\n <meta charset=\"UTF-8\">\r\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n <title>Authentication Failed</title>\r\n <style>\r\n body { font-family: sans-serif; display: flex; justify-content: center; align-items: center; height: 100vh; background-color: #f4f4f4; margin: 0; }\r\n .container { text-align: center; padding: 2em; background-color: #fff; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }\r\n h1 { color: #F44336; }\r\n p { color: #333; }\r\n </style>\r\n </head>\r\n <body>\r\n <div class=\"container\">\r\n <h1>Authentication Failed</h1>\r\n <p>An error occurred during authentication:</p>\r\n <p><code>${message}</code></p>\r\n <p>Please try again or check the server logs.</p>\r\n </div>\r\n </body>\r\n </html>\r\n `);\r\n }\r\n });\r\n }\r\n\r\n async start(openBrowser = true): Promise<boolean> {\r\n if (await this.tokenManager.validateTokens()) {\r\n this.authCompletedSuccessfully = true;\r\n return true;\r\n }\r\n \r\n // Try to start the server and get the port\r\n const port = await this.startServerOnAvailablePort();\r\n if (port === null) {\r\n this.authCompletedSuccessfully = false;\r\n return false;\r\n }\r\n\r\n // Successfully started server on `port`. Now create the flow-specific OAuth client.\r\n try {\r\n const { client_id, client_secret } = await loadCredentials();\r\n this.flowOAuth2Client = new OAuth2Client(\r\n client_id,\r\n client_secret || undefined,\r\n `http://localhost:${port}/oauth2callback`\r\n );\r\n } catch (error) {\r\n // Could not load credentials, cannot proceed with auth flow\r\n console.error('Failed to load credentials for auth flow:', error);\r\n this.authCompletedSuccessfully = false;\r\n await this.stop(); // Stop the server we just started\r\n return false;\r\n }\r\n\r\n if (openBrowser) {\r\n // Generate Auth URL using the newly created flow client\r\n const authorizeUrl = this.flowOAuth2Client.generateAuthUrl({\r\n access_type: 'offline',\r\n scope: SCOPES,\r\n prompt: 'consent'\r\n });\r\n \r\n console.error('\\n\uD83D\uDD10 AUTHENTICATION REQUIRED');\r\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');\r\n console.error('\\nOpening your browser to authenticate...');\r\n console.error(`If the browser doesn't open, visit:\\n${authorizeUrl}\\n`);\r\n \r\n await open(authorizeUrl);\r\n }\r\n\r\n return true; // Auth flow initiated\r\n }\r\n\r\n private async startServerOnAvailablePort(): Promise<number | null> {\r\n for (let port = this.portRange.start; port <= this.portRange.end; port++) {\r\n try {\r\n await new Promise<void>((resolve, reject) => {\r\n // Create a temporary server instance to test the port\r\n const testServer = this.app.listen(port, () => {\r\n this.server = testServer; // Assign to class property *only* if successful\r\n console.error(`Authentication server listening on http://localhost:${port}`);\r\n resolve();\r\n });\r\n testServer.on('error', (err: NodeJS.ErrnoException) => {\r\n if (err.code === 'EADDRINUSE') {\r\n // Port is in use, close the test server and reject\r\n testServer.close(() => reject(err)); \r\n } else {\r\n // Other error, reject\r\n reject(err);\r\n }\r\n });\r\n });\r\n return port; // Port successfully bound\r\n } catch (error: unknown) {\r\n // Check if it's EADDRINUSE, otherwise rethrow or handle\r\n if (!(error instanceof Error && 'code' in error && (error as any).code === 'EADDRINUSE')) {\r\n // An unexpected error occurred during server start\r\n console.error('Failed to start auth server:', error);\r\n return null;\r\n }\r\n // EADDRINUSE occurred, loop continues\r\n }\r\n }\r\n console.error('No available ports for authentication server (tried ports', this.portRange.start, '-', this.portRange.end, ')');\r\n return null; // No port found\r\n }\r\n\r\n public getRunningPort(): number | null {\r\n if (this.server) {\r\n const address = this.server.address();\r\n if (typeof address === 'object' && address !== null) {\r\n return address.port;\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n async stop(): Promise<void> {\r\n return new Promise((resolve, reject) => {\r\n if (this.server) {\r\n this.server.close((err) => {\r\n if (err) {\r\n reject(err);\r\n } else {\r\n this.server = null;\r\n resolve();\r\n }\r\n });\r\n } else {\r\n resolve();\r\n }\r\n });\r\n }\r\n}", "import { OAuth2Client, Credentials } from 'google-auth-library';\r\nimport * as fs from 'fs/promises';\r\nimport * as path from 'path';\r\nimport { getSecureTokenPath, getLegacyTokenPath, getAdditionalLegacyPaths } from './utils.js';\r\nimport { GaxiosError } from 'gaxios';\r\n\r\nexport class TokenManager {\r\n private oauth2Client: OAuth2Client;\r\n private tokenPath: string;\r\n\r\n constructor(oauth2Client: OAuth2Client) {\r\n this.oauth2Client = oauth2Client;\r\n this.tokenPath = getSecureTokenPath();\r\n this.setupTokenRefresh();\r\n }\r\n\r\n // Method to expose the token path\r\n public getTokenPath(): string {\r\n return this.tokenPath;\r\n }\r\n\r\n private async ensureTokenDirectoryExists(): Promise<void> {\r\n try {\r\n const dir = path.dirname(this.tokenPath);\r\n await fs.mkdir(dir, { recursive: true });\r\n } catch (error: unknown) {\r\n // Ignore errors if directory already exists, re-throw others\r\n if (error instanceof Error && 'code' in error && (error as any).code !== 'EEXIST') {\r\n console.error('Failed to create token directory:', error);\r\n throw error;\r\n }\r\n }\r\n }\r\n\r\n private setupTokenRefresh(): void {\r\n this.oauth2Client.on(\"tokens\", async (newTokens) => {\r\n try {\r\n await this.ensureTokenDirectoryExists();\r\n const currentTokens = JSON.parse(await fs.readFile(this.tokenPath, \"utf-8\"));\r\n const updatedTokens = {\r\n ...currentTokens,\r\n ...newTokens,\r\n refresh_token: newTokens.refresh_token || currentTokens.refresh_token,\r\n };\r\n await fs.writeFile(this.tokenPath, JSON.stringify(updatedTokens, null, 2), {\r\n mode: 0o600,\r\n });\r\n console.error(\"Tokens updated and saved\");\r\n } catch (error: unknown) {\r\n // Handle case where currentTokens might not exist yet\r\n if (error instanceof Error && 'code' in error && (error as any).code === 'ENOENT') { \r\n try {\r\n await fs.writeFile(this.tokenPath, JSON.stringify(newTokens, null, 2), { mode: 0o600 });\r\n console.error(\"New tokens saved\");\r\n } catch (writeError) {\r\n console.error(\"Error saving initial tokens:\", writeError);\r\n }\r\n } else {\r\n console.error(\"Error saving updated tokens:\", error);\r\n }\r\n }\r\n });\r\n }\r\n\r\n private async migrateLegacyTokens(): Promise<boolean> {\r\n // Check all possible legacy locations\r\n const legacyPaths = [getLegacyTokenPath(), ...getAdditionalLegacyPaths()];\r\n \r\n for (const legacyPath of legacyPaths) {\r\n try {\r\n // Check if legacy tokens exist\r\n if (!(await fs.access(legacyPath).then(() => true).catch(() => false))) {\r\n continue; // Try next location\r\n }\r\n\r\n // Read legacy tokens\r\n const legacyTokens = JSON.parse(await fs.readFile(legacyPath, \"utf-8\"));\r\n \r\n if (!legacyTokens || typeof legacyTokens !== \"object\") {\r\n console.error(\"Invalid legacy token format at\", legacyPath, \", skipping\");\r\n continue;\r\n }\r\n\r\n // Ensure new token directory exists\r\n await this.ensureTokenDirectoryExists();\r\n \r\n // Copy to new location\r\n await fs.writeFile(this.tokenPath, JSON.stringify(legacyTokens, null, 2), {\r\n mode: 0o600,\r\n });\r\n \r\n console.error(\"Migrated tokens from legacy location:\", legacyPath, \"to:\", this.tokenPath);\r\n \r\n // Optionally remove legacy file after successful migration\r\n try {\r\n await fs.unlink(legacyPath);\r\n console.error(\"Removed legacy token file\");\r\n } catch (unlinkErr) {\r\n console.error(\"Warning: Could not remove legacy token file:\", unlinkErr);\r\n }\r\n \r\n return true;\r\n } catch (error) {\r\n console.error(\"Error migrating legacy tokens from\", legacyPath, \":\", error);\r\n // Continue to next location\r\n }\r\n }\r\n \r\n return false; // No legacy tokens found or migrated\r\n }\r\n\r\n async loadSavedTokens(): Promise<boolean> {\r\n try {\r\n await this.ensureTokenDirectoryExists();\r\n \r\n // Check if current token file exists\r\n const tokenExists = await fs.access(this.tokenPath).then(() => true).catch(() => false);\r\n \r\n // If no current tokens, try to migrate from legacy location\r\n if (!tokenExists) {\r\n const migrated = await this.migrateLegacyTokens();\r\n if (!migrated) {\r\n console.error(\"No token file found at:\", this.tokenPath);\r\n return false;\r\n }\r\n }\r\n\r\n const tokens = JSON.parse(await fs.readFile(this.tokenPath, \"utf-8\"));\r\n\r\n if (!tokens || typeof tokens !== \"object\") {\r\n console.error(\"Invalid token format in file:\", this.tokenPath);\r\n return false;\r\n }\r\n\r\n this.oauth2Client.setCredentials(tokens);\r\n console.error('Tokens loaded and set on OAuth2Client:', {\r\n hasAccessToken: !!tokens.access_token,\r\n hasRefreshToken: !!tokens.refresh_token,\r\n tokenLength: tokens.access_token?.length,\r\n expiryDate: tokens.expiry_date,\r\n scope: tokens.scope\r\n });\r\n console.error('OAuth2Client after setCredentials:', {\r\n hasCredentials: !!this.oauth2Client.credentials,\r\n credentialsAccessToken: !!this.oauth2Client.credentials?.access_token\r\n });\r\n return true;\r\n } catch (error: unknown) {\r\n console.error(\"Error loading tokens:\", error);\r\n // Attempt to delete potentially corrupted token file\r\n if (error instanceof Error && 'code' in error && (error as any).code !== 'ENOENT') { \r\n try { \r\n await fs.unlink(this.tokenPath); \r\n console.error(\"Removed potentially corrupted token file\") \r\n } catch (unlinkErr) { /* ignore */ } \r\n }\r\n return false;\r\n }\r\n }\r\n\r\n async refreshTokensIfNeeded(): Promise<boolean> {\r\n const expiryDate = this.oauth2Client.credentials.expiry_date;\r\n const isExpired = expiryDate\r\n ? Date.now() >= expiryDate - 5 * 60 * 1000 // 5 minute buffer\r\n : !this.oauth2Client.credentials.access_token; // No token means we need one\r\n\r\n if (isExpired && this.oauth2Client.credentials.refresh_token) {\r\n console.error(\"Auth token expired or nearing expiry, refreshing...\");\r\n try {\r\n const response = await this.oauth2Client.refreshAccessToken();\r\n const newTokens = response.credentials;\r\n\r\n if (!newTokens.access_token) {\r\n throw new Error(\"Received invalid tokens during refresh\");\r\n }\r\n // The 'tokens' event listener should handle saving\r\n this.oauth2Client.setCredentials(newTokens);\r\n console.error(\"Token refreshed successfully\");\r\n return true;\r\n } catch (refreshError) {\r\n if (refreshError instanceof GaxiosError && refreshError.response?.data?.error === 'invalid_grant') {\r\n console.error(\"Error refreshing auth token: Invalid grant. Token likely expired or revoked. Please re-authenticate.\");\r\n // Optionally clear the potentially invalid tokens here\r\n await this.clearTokens(); \r\n return false; // Indicate failure due to invalid grant\r\n } else {\r\n // Handle other refresh errors\r\n console.error(\"Error refreshing auth token:\", refreshError);\r\n return false;\r\n }\r\n }\r\n } else if (!this.oauth2Client.credentials.access_token && !this.oauth2Client.credentials.refresh_token) {\r\n console.error(\"No access or refresh token available. Please re-authenticate.\");\r\n return false;\r\n } else {\r\n // Token is valid or no refresh token available\r\n return true;\r\n }\r\n }\r\n\r\n async validateTokens(): Promise<boolean> {\r\n if (!this.oauth2Client.credentials || !this.oauth2Client.credentials.access_token) {\r\n // Try loading first if no credentials set\r\n if (!(await this.loadSavedTokens())) {\r\n return false; // No saved tokens to load\r\n }\r\n // Check again after loading\r\n if (!this.oauth2Client.credentials || !this.oauth2Client.credentials.access_token) {\r\n return false; // Still no token after loading\r\n }\r\n }\r\n return this.refreshTokensIfNeeded();\r\n }\r\n\r\n async saveTokens(tokens: Credentials): Promise<void> {\r\n try {\r\n await this.ensureTokenDirectoryExists();\r\n await fs.writeFile(this.tokenPath, JSON.stringify(tokens, null, 2), { mode: 0o600 });\r\n this.oauth2Client.setCredentials(tokens);\r\n console.error(\"Tokens saved successfully to:\", this.tokenPath);\r\n } catch (error: unknown) {\r\n console.error(\"Error saving tokens:\", error);\r\n throw error;\r\n }\r\n }\r\n\r\n async clearTokens(): Promise<void> {\r\n try {\r\n this.oauth2Client.setCredentials({}); // Clear in memory\r\n await fs.unlink(this.tokenPath);\r\n console.error(\"Tokens cleared successfully\");\r\n } catch (error: unknown) {\r\n if (error instanceof Error && 'code' in error && (error as any).code === 'ENOENT') {\r\n // File already gone, which is fine\r\n console.error(\"Token file already deleted\");\r\n } else {\r\n console.error(\"Error clearing tokens:\", error);\r\n // Don't re-throw, clearing is best-effort\r\n }\r\n }\r\n }\r\n}", "// Main authentication module that re-exports and orchestrates the modular components\nimport { initializeOAuth2Client } from './auth/client.js';\nimport { AuthServer } from './auth/server.js';\nimport { TokenManager } from './auth/tokenManager.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<any> {\n console.error('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 console.error('Authentication successful - using existing tokens');\n console.error('OAuth2Client credentials:', {\n hasAccessToken: !!oauth2Client.credentials?.access_token,\n hasRefreshToken: !!oauth2Client.credentials?.refresh_token,\n expiryDate: oauth2Client.credentials?.expiry_date\n });\n return oauth2Client;\n }\n \n // No valid tokens, need to authenticate\n console.error('\\n\uD83D\uDD10 No valid authentication tokens found.');\n console.error('Starting authentication flow...\\n');\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/**\n * Manual authentication command\n * Used when running \"npm run auth\" or when the user needs to re-authenticate\n */\nexport async function runAuthCommand(): Promise<void> {\n try {\n console.error('Google Drive MCP - Manual Authentication');\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\\n');\n \n // Initialize OAuth client\n const oauth2Client = await initializeOAuth2Client();\n \n // Create and start the auth server\n const authServer = new AuthServer(oauth2Client);\n \n // Start with browser opening (true by default)\n const success = await authServer.start(true);\n \n if (!success && !authServer.authCompletedSuccessfully) {\n // Failed to start and tokens weren't already valid\n console.error(\n \"Authentication failed. Could not start server or validate existing tokens. Check port availability (3000-3004) and try again.\"\n );\n process.exit(1);\n } else if (authServer.authCompletedSuccessfully) {\n // Auth was successful (either existing tokens were valid or flow completed just now)\n console.error(\"\\n\u2705 Authentication successful!\");\n console.error(\"You can now use the Google Drive MCP server.\");\n process.exit(0); // Exit cleanly if auth is already done\n }\n \n // If we reach here, the server started and is waiting for the browser callback\n console.error(\n \"Authentication server started. Please complete the authentication in your browser...\"\n );\n \n // Wait for completion\n const intervalId = setInterval(async () => {\n if (authServer.authCompletedSuccessfully) {\n clearInterval(intervalId);\n await authServer.stop();\n console.error(\"\\n\u2705 Authentication completed successfully!\");\n console.error(\"You can now use the Google Drive MCP server.\");\n process.exit(0);\n }\n }, 1000);\n } catch (error) {\n console.error(\"\\n\u274C Authentication failed:\", error);\n process.exit(1);\n }\n}"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["__dirname", "OAuth2Client", "fs", "path", "OAuth2Client", "resolve", "resolve", "fileURLToPath", "join", "dirname"]
|
|
7
7
|
}
|