@piotr-agier/google-drive-mcp 2.1.0 → 2.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 +16 -2
- package/dist/index.js +100 -41
- package/dist/index.js.map +3 -3
- package/package.json +1 -1
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/scopes.ts", "../src/auth/externalAuth.ts", "../src/auth.ts", "../src/utils.ts", "../src/types.ts", "../src/tools/drive.ts", "../src/download-file.ts", "../src/tools/docs.ts", "../src/utils/driveImageUpload.ts", "../src/tools/sheets.ts", "../src/tools/slides.ts", "../src/tools/calendar.ts"],
|
|
4
|
-
"sourcesContent": ["#!/usr/bin/env node\n\nimport { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { StreamableHTTPServerTransport } from \"@modelcontextprotocol/sdk/server/streamableHttp.js\";\nimport { createMcpExpressApp } from \"@modelcontextprotocol/sdk/server/express.js\";\nimport {\n CallToolRequestSchema,\n ListResourcesRequestSchema,\n ListToolsRequestSchema,\n ReadResourceRequestSchema,\n isInitializeRequest,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { randomUUID } from 'crypto';\nimport { google } from \"googleapis\";\nimport type { drive_v3, calendar_v3 } from \"googleapis\";\nimport { authenticate, AuthServer, initializeOAuth2Client } from './auth.js';\nimport { fileURLToPath } from 'url';\nimport { readFileSync } from 'fs';\nimport { join, dirname } from 'path';\nimport {\n getExtensionFromFilename,\n escapeDriveQuery,\n} from './utils.js';\nimport type { ToolContext } from './types.js';\nimport { errorResponse } from './types.js';\n\nimport * as driveTools from './tools/drive.js';\nimport * as docsTools from './tools/docs.js';\nimport * as sheetsTools from './tools/sheets.js';\nimport * as slidesTools from './tools/slides.js';\nimport * as calendarTools from './tools/calendar.js';\n\n// Cached service instances \u2014 only recreated when authClient changes\nlet _drive: drive_v3.Drive | null = null;\nlet _calendar: calendar_v3.Calendar | null = null;\nlet _lastAuthClient: any = null;\n\nfunction getDrive(): drive_v3.Drive {\n if (!authClient) throw new Error('Authentication required');\n if (_drive && _lastAuthClient === authClient) return _drive;\n _drive = google.drive({ version: 'v3', auth: authClient });\n log('Drive service created');\n return _drive;\n}\n\nfunction getCalendar(): calendar_v3.Calendar {\n if (!authClient) throw new Error('Authentication required');\n if (_calendar && _lastAuthClient === authClient) return _calendar;\n _calendar = google.calendar({ version: 'v3', auth: authClient });\n log('Calendar service created');\n return _calendar;\n}\n\nconst FOLDER_MIME_TYPE = 'application/vnd.google-apps.folder';\n\n// Global auth client - will be initialized on first use\nlet authClient: any = null;\nlet authenticationPromise: Promise<any> | null = null;\n\n// Get package version\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst packageJsonPath = join(__dirname, '..', 'package.json');\nconst packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\nconst VERSION = packageJson.version;\n\n// -----------------------------------------------------------------------------\n// LOGGING UTILITY\n// -----------------------------------------------------------------------------\nfunction log(message: string, data?: any) {\n const timestamp = new Date().toISOString();\n const logMessage = data\n ? `[${timestamp}] ${message}: ${JSON.stringify(data)}`\n : `[${timestamp}] ${message}`;\n console.error(logMessage);\n}\n\n// -----------------------------------------------------------------------------\n// HELPER FUNCTIONS\n// -----------------------------------------------------------------------------\n\nasync function resolvePath(pathStr: string): Promise<string> {\n if (!pathStr || pathStr === '/') return 'root';\n\n const parts = pathStr.replace(/^\\/+|\\/+$/g, '').split('/');\n let currentFolderId: string = 'root';\n\n for (const part of parts) {\n if (!part) continue;\n const escapedPart = escapeDriveQuery(part);\n const response = await getDrive().files.list({\n q: `'${currentFolderId}' in parents and name = '${escapedPart}' and mimeType = '${FOLDER_MIME_TYPE}' and trashed = false`,\n fields: 'files(id)',\n spaces: 'drive',\n includeItemsFromAllDrives: true,\n supportsAllDrives: true\n });\n\n if (!response.data.files?.length) {\n const folderMetadata = {\n name: part,\n mimeType: FOLDER_MIME_TYPE,\n parents: [currentFolderId]\n };\n const folder = await getDrive().files.create({\n requestBody: folderMetadata,\n fields: 'id',\n supportsAllDrives: true\n });\n\n if (!folder.data.id) {\n throw new Error(`Failed to create intermediate folder: ${part}`);\n }\n\n currentFolderId = folder.data.id;\n } else {\n currentFolderId = response.data.files[0].id!;\n }\n }\n\n return currentFolderId;\n}\n\nasync function resolveFolderId(input: string | undefined): Promise<string> {\n if (!input) return 'root';\n\n if (input.startsWith('/')) {\n return resolvePath(input);\n } else {\n return input;\n }\n}\n\nfunction validateTextFileExtension(name: string) {\n const ext = getExtensionFromFilename(name);\n if (!['txt', 'md'].includes(ext)) {\n throw new Error(\"File name must end with .txt or .md for text files.\");\n }\n}\n\nasync function checkFileExists(name: string, parentFolderId: string = 'root'): Promise<string | null> {\n try {\n const escapedName = escapeDriveQuery(name);\n const query = `name = '${escapedName}' and '${parentFolderId}' in parents and trashed = false`;\n\n const res = await getDrive().files.list({\n q: query,\n fields: 'files(id, name, mimeType)',\n pageSize: 1,\n includeItemsFromAllDrives: true,\n supportsAllDrives: true\n });\n\n if (res.data.files && res.data.files.length > 0) {\n return res.data.files[0].id || null;\n }\n return null;\n } catch (error) {\n log('Error checking file existence:', error);\n return null;\n }\n}\n\n// -----------------------------------------------------------------------------\n// AUTHENTICATION HELPER\n// -----------------------------------------------------------------------------\nasync function ensureAuthenticated() {\n if (authClient) return;\n\n if (authenticationPromise) {\n log('Authentication already in progress, waiting...');\n authClient = await authenticationPromise;\n return;\n }\n\n log('Initializing authentication');\n authenticationPromise = authenticate();\n try {\n authClient = await authenticationPromise;\n log('Authentication complete');\n } finally {\n authenticationPromise = null;\n }\n}\n\n// -----------------------------------------------------------------------------\n// DOMAIN MODULES\n// -----------------------------------------------------------------------------\nconst domainModules = [driveTools, docsTools, sheetsTools, slidesTools, calendarTools];\n\nfunction buildToolContext(): ToolContext {\n return {\n authClient,\n google,\n getDrive,\n getCalendar,\n log,\n resolvePath,\n resolveFolderId,\n checkFileExists,\n validateTextFileExtension,\n };\n}\n\n// -----------------------------------------------------------------------------\n// SERVER FACTORY\n// -----------------------------------------------------------------------------\n\nfunction createMcpServer(): Server {\n const s = new Server(\n {\n name: \"google-drive-mcp\",\n version: VERSION,\n },\n {\n capabilities: {\n resources: {},\n tools: {},\n },\n },\n );\n\n s.setRequestHandler(ListResourcesRequestSchema, async (request) => {\n await ensureAuthenticated();\n log('Handling ListResources request', { params: request.params });\n const pageSize = 10;\n const params: {\n pageSize: number,\n fields: string,\n pageToken?: string,\n q: string,\n includeItemsFromAllDrives: boolean,\n supportsAllDrives: boolean\n } = {\n pageSize,\n fields: \"nextPageToken, files(id, name, mimeType)\",\n q: `trashed = false`,\n includeItemsFromAllDrives: true,\n supportsAllDrives: true\n };\n\n if (request.params?.cursor) {\n params.pageToken = request.params.cursor;\n }\n\n const res = await getDrive().files.list(params);\n log('Listed files', { count: res.data.files?.length });\n const files = res.data.files || [];\n\n return {\n resources: files.map((file: drive_v3.Schema$File) => ({\n uri: `gdrive:///${file.id}`,\n mimeType: file.mimeType || 'application/octet-stream',\n name: file.name || 'Untitled',\n })),\n nextCursor: res.data.nextPageToken,\n };\n });\n\n s.setRequestHandler(ReadResourceRequestSchema, async (request) => {\n await ensureAuthenticated();\n log('Handling ReadResource request', { uri: request.params.uri });\n const fileId = request.params.uri.replace(\"gdrive:///\", \"\");\n\n const file = await getDrive().files.get({\n fileId,\n fields: \"mimeType\",\n supportsAllDrives: true\n });\n const mimeType = file.data.mimeType;\n\n if (!mimeType) {\n throw new Error(\"File has no MIME type.\");\n }\n\n if (mimeType.startsWith(\"application/vnd.google-apps\")) {\n let exportMimeType;\n switch (mimeType) {\n case \"application/vnd.google-apps.document\": exportMimeType = \"text/markdown\"; break;\n case \"application/vnd.google-apps.spreadsheet\": exportMimeType = \"text/csv\"; break;\n case \"application/vnd.google-apps.presentation\": exportMimeType = \"text/plain\"; break;\n case \"application/vnd.google-apps.drawing\": exportMimeType = \"image/png\"; break;\n default: exportMimeType = \"text/plain\"; break;\n }\n\n const res = await getDrive().files.export(\n { fileId, mimeType: exportMimeType },\n { responseType: \"text\" },\n );\n\n log('Successfully read resource', { fileId, mimeType });\n return {\n contents: [\n {\n uri: request.params.uri,\n mimeType: exportMimeType,\n text: res.data,\n },\n ],\n };\n } else {\n const res = await getDrive().files.get(\n { fileId, alt: \"media\", supportsAllDrives: true },\n { responseType: \"arraybuffer\" },\n );\n const contentMime = mimeType || \"application/octet-stream\";\n\n if (contentMime.startsWith(\"text/\") || contentMime === \"application/json\") {\n return {\n contents: [\n {\n uri: request.params.uri,\n mimeType: contentMime,\n text: Buffer.from(res.data as ArrayBuffer).toString(\"utf-8\"),\n },\n ],\n };\n } else {\n return {\n contents: [\n {\n uri: request.params.uri,\n mimeType: contentMime,\n blob: Buffer.from(res.data as ArrayBuffer).toString(\"base64\"),\n },\n ],\n };\n }\n }\n });\n\n s.setRequestHandler(ListToolsRequestSchema, async () => {\n return {\n tools: domainModules.flatMap(m => m.toolDefinitions),\n };\n });\n\n s.setRequestHandler(CallToolRequestSchema, async (request) => {\n await ensureAuthenticated();\n log('Handling tool request', { tool: request.params.name });\n\n const ctx = buildToolContext();\n\n try {\n for (const mod of domainModules) {\n const result = await mod.handleTool(request.params.name, request.params.arguments ?? {}, ctx);\n if (result !== null) return result;\n }\n return errorResponse(\"Tool not found\");\n } catch (error) {\n log('Error in tool request handler', { error: (error as Error).message });\n return errorResponse((error as Error).message);\n }\n });\n\n return s;\n}\n\n// Module-level server instance (used by stdio mode and tests)\nconst server = createMcpServer();\n\n// -----------------------------------------------------------------------------\n// CLI FUNCTIONS\n// -----------------------------------------------------------------------------\n\nfunction showHelp(): void {\n console.log(`\nGoogle Drive MCP Server v${VERSION}\n\nUsage:\n npx @yourusername/google-drive-mcp [command] [options]\n\nCommands:\n auth Run the authentication flow\n start Start the MCP server (default)\n version Show version information\n help Show this help message\n\nTransport Options:\n --transport <stdio|http> Transport mode (default: stdio)\n --port <number> HTTP listen port (default: 3100)\n --host <address> HTTP bind address (default: 127.0.0.1)\n\nExamples:\n npx @yourusername/google-drive-mcp auth\n npx @yourusername/google-drive-mcp start\n npx @yourusername/google-drive-mcp start --transport http --port 3100\n npx @yourusername/google-drive-mcp version\n npx @yourusername/google-drive-mcp\n\nEnvironment Variables:\n GOOGLE_DRIVE_OAUTH_CREDENTIALS Path to OAuth credentials file\n GOOGLE_DRIVE_MCP_TOKEN_PATH Path to store authentication tokens\n\n Transport Configuration:\n MCP_TRANSPORT Transport mode: stdio or http (default: stdio)\n MCP_HTTP_PORT HTTP listen port (default: 3100)\n MCP_HTTP_HOST HTTP bind address (default: 127.0.0.1)\n\n Service Account Mode:\n GOOGLE_APPLICATION_CREDENTIALS Path to service account JSON key file\n\n External OAuth Token Mode:\n GOOGLE_DRIVE_MCP_ACCESS_TOKEN Pre-obtained Google OAuth access token\n GOOGLE_DRIVE_MCP_REFRESH_TOKEN Refresh token for auto-refresh (optional)\n GOOGLE_DRIVE_MCP_CLIENT_ID OAuth client ID (required with refresh token)\n GOOGLE_DRIVE_MCP_CLIENT_SECRET OAuth client secret (required with refresh token)\n`);\n}\n\nfunction showVersion(): void {\n console.log(`Google Drive MCP Server v${VERSION}`);\n}\n\nasync function runAuthServer(): Promise<void> {\n try {\n const oauth2Client = await initializeOAuth2Client();\n const authServerInstance = new AuthServer(oauth2Client);\n const success = await authServerInstance.start(true);\n\n if (!success && !authServerInstance.authCompletedSuccessfully) {\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 (authServerInstance.authCompletedSuccessfully) {\n console.log(\"Authentication successful.\");\n process.exit(0);\n }\n\n console.log(\n \"Authentication server started. Please complete the authentication in your browser...\"\n );\n\n const intervalId = setInterval(async () => {\n if (authServerInstance.authCompletedSuccessfully) {\n clearInterval(intervalId);\n await authServerInstance.stop();\n console.log(\"Authentication completed successfully!\");\n process.exit(0);\n }\n }, 1000);\n } catch (error) {\n console.error(\"Authentication failed:\", error);\n process.exit(1);\n }\n}\n\n// -----------------------------------------------------------------------------\n// MAIN EXECUTION\n// -----------------------------------------------------------------------------\n\ninterface CliArgs {\n command: string | undefined;\n transport: 'stdio' | 'http';\n httpPort: number;\n httpHost: string;\n}\n\nfunction parseCliArgs(): CliArgs {\n const args = process.argv.slice(2);\n let command: string | undefined;\n let transport: string | undefined;\n let httpPort: string | undefined;\n let httpHost: string | undefined;\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n\n if (arg === '--version' || arg === '-v' || arg === '--help' || arg === '-h') {\n command = arg;\n continue;\n }\n\n if (arg === '--transport' && i + 1 < args.length) {\n transport = args[++i];\n continue;\n }\n if (arg === '--port' && i + 1 < args.length) {\n httpPort = args[++i];\n continue;\n }\n if (arg === '--host' && i + 1 < args.length) {\n httpHost = args[++i];\n continue;\n }\n\n if (!command && !arg.startsWith('--')) {\n command = arg;\n continue;\n }\n }\n\n const resolvedTransport = transport || process.env.MCP_TRANSPORT || 'stdio';\n if (resolvedTransport !== 'stdio' && resolvedTransport !== 'http') {\n console.error(`Invalid transport: ${resolvedTransport}. Must be \"stdio\" or \"http\".`);\n process.exit(1);\n }\n\n const resolvedPort = parseInt(httpPort || process.env.MCP_HTTP_PORT || '3100', 10);\n if (isNaN(resolvedPort) || resolvedPort < 1 || resolvedPort > 65535) {\n console.error(`Invalid port: ${httpPort || process.env.MCP_HTTP_PORT}. Must be 1-65535.`);\n process.exit(1);\n }\n\n return {\n command,\n transport: resolvedTransport,\n httpPort: resolvedPort,\n httpHost: httpHost || process.env.MCP_HTTP_HOST || '127.0.0.1',\n };\n}\n\nasync function main() {\n const args = parseCliArgs();\n\n switch (args.command) {\n case \"auth\":\n await runAuthServer();\n break;\n case \"start\":\n case undefined:\n if (args.transport === 'http') {\n await startHttpTransport(args);\n } else {\n await startStdioTransport();\n }\n break;\n case \"version\":\n case \"--version\":\n case \"-v\":\n showVersion();\n break;\n case \"help\":\n case \"--help\":\n case \"-h\":\n showHelp();\n break;\n default:\n console.error(`Unknown command: ${args.command}`);\n showHelp();\n process.exit(1);\n }\n}\n\nasync function startStdioTransport(): Promise<void> {\n try {\n console.error(\"Starting Google Drive MCP server (stdio)...\");\n const transport = new StdioServerTransport();\n await server.connect(transport);\n log('Server started successfully');\n\n process.on(\"SIGINT\", async () => {\n await server.close();\n process.exit(0);\n });\n process.on(\"SIGTERM\", async () => {\n await server.close();\n process.exit(0);\n });\n } catch (error) {\n console.error('Failed to start server:', error);\n process.exit(1);\n }\n}\n\ninterface HttpSession {\n transport: StreamableHTTPServerTransport;\n server: Server;\n}\n\n/**\n * Create an Express app with MCP Streamable HTTP routes.\n * Shared by production (startHttpTransport) and tests.\n */\nconst SESSION_IDLE_TIMEOUT_MS = 30 * 60 * 1000; // 30 minutes\n\ninterface CreateHttpAppOptions {\n sessionIdleTimeoutMs?: number;\n}\n\nfunction createHttpApp(host: string, options?: CreateHttpAppOptions) {\n const idleTimeoutMs = options?.sessionIdleTimeoutMs ?? SESSION_IDLE_TIMEOUT_MS;\n const app = createMcpExpressApp({ host });\n const sessions = new Map<string, HttpSession>();\n const sessionTimers = new Map<string, ReturnType<typeof setTimeout>>();\n\n function resetSessionTimer(sid: string) {\n const existing = sessionTimers.get(sid);\n if (existing) clearTimeout(existing);\n sessionTimers.set(sid, setTimeout(async () => {\n const session = sessions.get(sid);\n if (session) {\n log(`Session idle timeout: ${sid}`);\n await session.transport.close();\n await session.server.close();\n sessions.delete(sid);\n }\n sessionTimers.delete(sid);\n }, idleTimeoutMs));\n }\n\n function clearSessionTimer(sid: string) {\n const timer = sessionTimers.get(sid);\n if (timer) {\n clearTimeout(timer);\n sessionTimers.delete(sid);\n }\n }\n\n app.post('/mcp', async (req, res) => {\n try {\n const sessionId = req.headers['mcp-session-id'] as string | undefined;\n\n // If we have an existing session, delegate to it\n if (sessionId && sessions.has(sessionId)) {\n const session = sessions.get(sessionId)!;\n resetSessionTimer(sessionId);\n await session.transport.handleRequest(req, res, req.body);\n return;\n }\n\n // New session: only accept initialize requests\n if (!isInitializeRequest(req.body)) {\n res.status(400).json({\n jsonrpc: '2.0',\n error: { code: -32600, message: 'Bad Request: expected initialize request or valid session ID' },\n id: null,\n });\n return;\n }\n\n // Create a new session\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: () => randomUUID(),\n });\n const sessionServer = createMcpServer();\n\n await sessionServer.connect(transport);\n\n // Track the session once we know its ID (set after handleRequest processes init)\n transport.onclose = () => {\n const sid = transport.sessionId;\n if (sid) {\n clearSessionTimer(sid);\n sessions.delete(sid);\n log(`Session closed: ${sid}`);\n }\n };\n\n await transport.handleRequest(req, res, req.body);\n\n const sid = transport.sessionId;\n if (sid) {\n sessions.set(sid, { transport, server: sessionServer });\n resetSessionTimer(sid);\n log(`New session created: ${sid}`);\n }\n } catch (error) {\n log('Error handling POST /mcp', { error: (error as Error).message });\n if (!res.headersSent) {\n res.status(500).json({\n jsonrpc: '2.0',\n error: { code: -32603, message: 'Internal server error' },\n id: null,\n });\n }\n }\n });\n\n app.get('/mcp', async (req, res) => {\n try {\n const sessionId = req.headers['mcp-session-id'] as string | undefined;\n if (!sessionId || !sessions.has(sessionId)) {\n res.status(400).json({\n jsonrpc: '2.0',\n error: { code: -32600, message: 'Bad Request: missing or invalid session ID' },\n id: null,\n });\n return;\n }\n const session = sessions.get(sessionId)!;\n resetSessionTimer(sessionId);\n await session.transport.handleRequest(req, res);\n } catch (error) {\n log('Error handling GET /mcp', { error: (error as Error).message });\n if (!res.headersSent) {\n res.status(500).json({\n jsonrpc: '2.0',\n error: { code: -32603, message: 'Internal server error' },\n id: null,\n });\n }\n }\n });\n\n app.delete('/mcp', async (req, res) => {\n try {\n const sessionId = req.headers['mcp-session-id'] as string | undefined;\n if (!sessionId || !sessions.has(sessionId)) {\n res.status(400).json({\n jsonrpc: '2.0',\n error: { code: -32600, message: 'Bad Request: missing or invalid session ID' },\n id: null,\n });\n return;\n }\n const session = sessions.get(sessionId)!;\n await session.transport.close();\n await session.server.close();\n sessions.delete(sessionId);\n res.status(200).end();\n } catch (error) {\n log('Error handling DELETE /mcp', { error: (error as Error).message });\n if (!res.headersSent) {\n res.status(500).json({\n jsonrpc: '2.0',\n error: { code: -32603, message: 'Internal server error' },\n id: null,\n });\n }\n }\n });\n\n return { app, sessions };\n}\n\nasync function startHttpTransport(args: CliArgs): Promise<void> {\n try {\n const { httpPort, httpHost } = args;\n console.error(`Starting Google Drive MCP server (HTTP on ${httpHost}:${httpPort})...`);\n\n const { app, sessions } = createHttpApp(httpHost);\n\n const httpServer = app.listen(httpPort, httpHost, () => {\n log(`HTTP server listening on ${httpHost}:${httpPort}`);\n });\n\n const shutdown = async () => {\n log('Shutting down HTTP server...');\n for (const [sid, session] of sessions) {\n await session.transport.close();\n await session.server.close();\n sessions.delete(sid);\n }\n httpServer.close();\n process.exit(0);\n };\n\n process.on(\"SIGINT\", shutdown);\n process.on(\"SIGTERM\", shutdown);\n } catch (error) {\n console.error('Failed to start HTTP server:', error);\n process.exit(1);\n }\n}\n\n// Export server, factory, and main for testing or potential programmatic use\nexport { main, server, createMcpServer, createHttpApp };\n\n/** Inject a fake auth client for testing \u2014 bypasses authenticate(). */\nexport function _setAuthClientForTesting(client: any) {\n authClient = client;\n _drive = null;\n _calendar = null;\n _lastAuthClient = null;\n}\n\n// Run the CLI (skip when imported by tests)\nif (!process.env.MCP_TESTING) {\n main().catch((error) => {\n console.error(\"Fatal error:\", error);\n process.exit(1);\n });\n}\n", "import { OAuth2Client } from 'google-auth-library';\nimport * as fs from 'fs/promises';\nimport { getKeysFilePaths, generateCredentialsErrorMessage, OAuthCredentials } from './utils.js';\n\nfunction parseCredentialsFile(keys: Record<string, unknown>): OAuthCredentials {\n if (keys.installed) {\n const { client_id, client_secret, redirect_uris } = keys.installed as OAuthCredentials;\n return { client_id, client_secret, redirect_uris };\n } else if (keys.web) {\n const { client_id, client_secret, redirect_uris } = keys.web as OAuthCredentials;\n return { client_id, client_secret, redirect_uris };\n } else if (keys.client_id) {\n return {\n client_id: keys.client_id as string,\n client_secret: keys.client_secret as string | undefined,\n redirect_uris: (keys.redirect_uris as string[] | undefined) || ['http://localhost:3000/oauth2callback']\n };\n } else {\n throw new Error('Invalid credentials file format. Expected either \"installed\", \"web\" object or direct client_id field.');\n }\n}\n\nasync function loadCredentialsFromFile(): Promise<OAuthCredentials> {\n const paths = getKeysFilePaths();\n\n for (const keysPath of paths) {\n try {\n const keysContent = await fs.readFile(keysPath, \"utf-8\");\n const keys = JSON.parse(keysContent);\n return parseCredentialsFile(keys);\n } catch (err: unknown) {\n // Re-throw parse/validation errors so the user gets actionable feedback\n if (err instanceof SyntaxError ||\n (err instanceof Error && err.message.includes('Invalid credentials'))) {\n throw new Error(`Invalid credentials file at ${keysPath}: ${(err as Error).message}`);\n }\n // File not found \u2014 try next path\n }\n }\n\n throw new Error(`Credentials file not found. Searched: ${paths.join(', ')}`);\n}\n\nasync function loadCredentialsWithFallback(): Promise<OAuthCredentials> {\n try {\n return await loadCredentialsFromFile();\n } catch (fileError) {\n // Check for legacy client_secret.json\n const legacyPath = process.env.GOOGLE_CLIENT_SECRET_PATH || 'client_secret.json';\n try {\n const legacyContent = await fs.readFile(legacyPath, 'utf-8');\n const legacyKeys = JSON.parse(legacyContent);\n console.error('Warning: Using legacy client_secret.json. Please migrate to gcp-oauth.keys.json');\n \n if (legacyKeys.installed) {\n return legacyKeys.installed;\n } else if (legacyKeys.web) {\n return legacyKeys.web;\n } else {\n throw new Error('Invalid legacy credentials format');\n }\n } catch (_legacyError) {\n // Generate helpful error message\n const errorMessage = generateCredentialsErrorMessage();\n throw new Error(`${errorMessage}\\n\\nOriginal error: ${fileError instanceof Error ? fileError.message : fileError}`);\n }\n }\n}\n\nexport async function initializeOAuth2Client(): Promise<OAuth2Client> {\n try {\n const credentials = await loadCredentialsWithFallback();\n \n // Use the first redirect URI as the default for the base client\n return new OAuth2Client({\n clientId: credentials.client_id,\n clientSecret: credentials.client_secret || undefined,\n redirectUri: credentials.redirect_uris?.[0] || 'http://localhost:3000/oauth2callback',\n });\n } catch (error) {\n throw new Error(`Error loading OAuth keys: ${error instanceof Error ? error.message : error}`);\n }\n}\n\nexport async function loadCredentials(): Promise<{ client_id: string; client_secret?: string }> {\n try {\n const credentials = await loadCredentialsWithFallback();\n \n if (!credentials.client_id) {\n throw new Error('Client ID missing in credentials.');\n }\n return {\n client_id: credentials.client_id,\n client_secret: credentials.client_secret\n };\n } catch (error) {\n throw new Error(`Error loading credentials: ${error instanceof Error ? error.message : error}`);\n }\n}", "import * as path from 'path';\nimport * as os from 'os';\nimport { fileURLToPath } from 'url';\n\n// Helper to get the project root directory reliably\nfunction getProjectRoot(): string {\n const __dirname = path.dirname(fileURLToPath(import.meta.url));\n // In build output (e.g., dist/auth/utils.js), __dirname is .../dist/auth\n // Go up TWO levels to get the project root\n const projectRoot = path.join(__dirname, \"..\", \"..\");\n return path.resolve(projectRoot);\n}\n\n// Returns the config directory for google-drive-mcp, following XDG Base Directory spec.\nfunction getConfigDir(): string {\n const configHome = process.env.XDG_CONFIG_HOME ||\n path.join(os.homedir(), '.config');\n return path.join(configHome, 'google-drive-mcp');\n}\n\n// Returns the absolute path for the saved token file.\n// Uses XDG Base Directory spec with fallback to home directory\nexport function getSecureTokenPath(): string {\n // Check for custom token path environment variable first\n const customTokenPath = process.env.GOOGLE_DRIVE_MCP_TOKEN_PATH;\n if (customTokenPath) {\n return path.resolve(customTokenPath);\n }\n\n return path.join(getConfigDir(), 'tokens.json');\n}\n\n// Returns the legacy token path for backward compatibility\nexport function getLegacyTokenPath(): string {\n const projectRoot = getProjectRoot();\n return path.join(projectRoot, \".gcp-saved-tokens.json\");\n}\n\n// Additional legacy paths to check\nexport function getAdditionalLegacyPaths(): string[] {\n return [\n process.env.GOOGLE_TOKEN_PATH,\n path.join(process.cwd(), 'google-tokens.json'),\n path.join(process.cwd(), '.gcp-saved-tokens.json')\n ].filter(Boolean) as string[];\n}\n\n// Returns all candidate paths for the credentials file, in priority order:\n// 1. Environment variable GOOGLE_DRIVE_OAUTH_CREDENTIALS (highest priority)\n// 2. Config directory ~/.config/google-drive-mcp/gcp-oauth.keys.json\n// 3. Project root directory (legacy fallback)\nexport function getKeysFilePaths(): string[] {\n const paths: string[] = [];\n\n const envCredentialsPath = process.env.GOOGLE_DRIVE_OAUTH_CREDENTIALS;\n if (envCredentialsPath) {\n paths.push(path.resolve(envCredentialsPath));\n }\n\n paths.push(path.join(getConfigDir(), 'gcp-oauth.keys.json'));\n\n const projectRoot = getProjectRoot();\n paths.push(path.join(projectRoot, \"gcp-oauth.keys.json\"));\n\n return paths;\n}\n\n// Interface for OAuth credentials\nexport interface OAuthCredentials {\n client_id: string;\n client_secret?: string;\n redirect_uris?: string[];\n}\n\n// Generate helpful error message for missing credentials\nexport function generateCredentialsErrorMessage(): string {\n const configDir = getConfigDir();\n\n return `\nOAuth credentials not found. Please provide credentials using one of these methods:\n\n1. Config directory (recommended):\n Place your gcp-oauth.keys.json file in: ${configDir}/\n\n2. Environment variable:\n Set GOOGLE_DRIVE_OAUTH_CREDENTIALS to the path of your credentials file:\n export GOOGLE_DRIVE_OAUTH_CREDENTIALS=\"/path/to/gcp-oauth.keys.json\"\n\nToken storage:\n- Tokens are saved to: ${getSecureTokenPath()}\n- To use a custom token location, set GOOGLE_DRIVE_MCP_TOKEN_PATH environment variable\n\nTo get OAuth credentials:\n1. Go to the Google Cloud Console (https://console.cloud.google.com/)\n2. Create or select a project\n3. Enable the Google Drive, Docs, Sheets, and Slides APIs\n4. Create OAuth 2.0 credentials (Desktop app type)\n5. Download the credentials file as gcp-oauth.keys.json\n`.trim();\n}", "import express from 'express';\nimport { OAuth2Client } from 'google-auth-library';\nimport { TokenManager } from './tokenManager.js';\nimport http from 'http';\nimport open from 'open';\nimport { loadCredentials } from './client.js';\nimport { resolveOAuthScopes } from './scopes.js';\n\nconst SCOPES = resolveOAuthScopes();\n\nexport class AuthServer {\n private baseOAuth2Client: OAuth2Client; // Used by TokenManager for validation/refresh\n private flowOAuth2Client: OAuth2Client | null = null; // Used specifically for the auth code flow\n private app: express.Express;\n private server: http.Server | null = null;\n private tokenManager: TokenManager;\n private portRange: { start: number; end: number };\n public authCompletedSuccessfully = false; // Flag for standalone script\n\n constructor(oauth2Client: OAuth2Client) {\n this.baseOAuth2Client = oauth2Client;\n this.tokenManager = new TokenManager(oauth2Client);\n this.app = express();\n this.portRange = { start: 3000, end: 3004 };\n this.setupRoutes();\n }\n\n private setupRoutes(): void {\n this.app.get('/', (req, res) => {\n // Generate the URL using the active flow client if available, else base\n const clientForUrl = this.flowOAuth2Client || this.baseOAuth2Client;\n const authUrl = clientForUrl.generateAuthUrl({\n access_type: 'offline',\n scope: SCOPES,\n prompt: 'consent'\n });\n res.send(`<h1>Google Drive Authentication</h1><a href=\"${authUrl}\">Authenticate with Google</a>`);\n });\n\n this.app.get('/oauth2callback', async (req, res) => {\n const code = req.query.code as string;\n if (!code) {\n res.status(400).send('Authorization code missing');\n return;\n }\n // IMPORTANT: Use the flowOAuth2Client to exchange the code\n if (!this.flowOAuth2Client) {\n res.status(500).send('Authentication flow not properly initiated.');\n return;\n }\n try {\n const { tokens } = await this.flowOAuth2Client.getToken(code);\n // Save tokens using the TokenManager (which uses the base client)\n await this.tokenManager.saveTokens(tokens);\n this.authCompletedSuccessfully = true;\n\n // Get the path where tokens were saved\n const tokenPath = this.tokenManager.getTokenPath();\n\n // Send a more informative HTML response including the path\n res.send(`\n <!DOCTYPE html>\n <html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Authentication Successful</title>\n <style>\n body { font-family: sans-serif; display: flex; justify-content: center; align-items: center; height: 100vh; background-color: #f4f4f4; margin: 0; }\n .container { text-align: center; padding: 2em; background-color: #fff; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }\n h1 { color: #4CAF50; }\n p { color: #333; margin-bottom: 0.5em; }\n code { background-color: #eee; padding: 0.2em 0.4em; border-radius: 3px; font-size: 0.9em; }\n </style>\n </head>\n <body>\n <div class=\"container\">\n <h1>Authentication Successful!</h1>\n <p>Your authentication tokens have been saved successfully to:</p>\n <p><code>${tokenPath}</code></p>\n <p>You can now close this browser window.</p>\n </div>\n </body>\n </html>\n `);\n } catch (error: unknown) {\n this.authCompletedSuccessfully = false;\n const message = error instanceof Error ? error.message : 'Unknown error';\n // Send an HTML error response\n res.status(500).send(`\n <!DOCTYPE html>\n <html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Authentication Failed</title>\n <style>\n body { font-family: sans-serif; display: flex; justify-content: center; align-items: center; height: 100vh; background-color: #f4f4f4; margin: 0; }\n .container { text-align: center; padding: 2em; background-color: #fff; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }\n h1 { color: #F44336; }\n p { color: #333; }\n </style>\n </head>\n <body>\n <div class=\"container\">\n <h1>Authentication Failed</h1>\n <p>An error occurred during authentication:</p>\n <p><code>${message}</code></p>\n <p>Please try again or check the server logs.</p>\n </div>\n </body>\n </html>\n `);\n }\n });\n }\n\n async start(openBrowser = true): Promise<boolean> {\n if (await this.tokenManager.validateTokens()) {\n this.authCompletedSuccessfully = true;\n return true;\n }\n \n // Try to start the server and get the port\n const port = await this.startServerOnAvailablePort();\n if (port === null) {\n this.authCompletedSuccessfully = false;\n return false;\n }\n\n // Successfully started server on `port`. Now create the flow-specific OAuth client.\n try {\n const { client_id, client_secret } = await loadCredentials();\n this.flowOAuth2Client = new OAuth2Client(\n client_id,\n client_secret || undefined,\n `http://localhost:${port}/oauth2callback`\n );\n } catch (error) {\n // Could not load credentials, cannot proceed with auth flow\n console.error('Failed to load credentials for auth flow:', error);\n this.authCompletedSuccessfully = false;\n await this.stop(); // Stop the server we just started\n return false;\n }\n\n if (openBrowser) {\n // Generate Auth URL using the newly created flow client\n const authorizeUrl = this.flowOAuth2Client.generateAuthUrl({\n access_type: 'offline',\n scope: SCOPES,\n prompt: 'consent'\n });\n \n console.error('\\n\uD83D\uDD10 AUTHENTICATION REQUIRED');\n console.error('\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550');\n console.error('\\nOpening your browser to authenticate...');\n console.error(`If the browser doesn't open, visit:\\n${authorizeUrl}\\n`);\n \n await open(authorizeUrl);\n }\n\n return true; // Auth flow initiated\n }\n\n private async startServerOnAvailablePort(): Promise<number | null> {\n for (let port = this.portRange.start; port <= this.portRange.end; port++) {\n try {\n await new Promise<void>((resolve, reject) => {\n // Create a temporary server instance to test the port\n const testServer = this.app.listen(port, () => {\n this.server = testServer; // Assign to class property *only* if successful\n console.error(`Authentication server listening on http://localhost:${port}`);\n resolve();\n });\n testServer.on('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'EADDRINUSE') {\n // Port is in use, close the test server and reject\n testServer.close(() => reject(err)); \n } else {\n // Other error, reject\n reject(err);\n }\n });\n });\n return port; // Port successfully bound\n } catch (error: unknown) {\n // Check if it's EADDRINUSE, otherwise rethrow or handle\n if (!(error instanceof Error && 'code' in error && (error as any).code === 'EADDRINUSE')) {\n // An unexpected error occurred during server start\n console.error('Failed to start auth server:', error);\n return null;\n }\n // EADDRINUSE occurred, loop continues\n }\n }\n console.error('No available ports for authentication server (tried ports', this.portRange.start, '-', this.portRange.end, ')');\n return null; // No port found\n }\n\n public getRunningPort(): number | null {\n if (this.server) {\n const address = this.server.address();\n if (typeof address === 'object' && address !== null) {\n return address.port;\n }\n }\n return null;\n }\n\n async stop(): Promise<void> {\n return new Promise((resolve, reject) => {\n if (this.server) {\n this.server.close((err) => {\n if (err) {\n reject(err);\n } else {\n this.server = null;\n resolve();\n }\n });\n } else {\n resolve();\n }\n });\n }\n}", "import { OAuth2Client, Credentials } from 'google-auth-library';\nimport * as fs from 'fs/promises';\nimport * as path from 'path';\nimport { getSecureTokenPath, getLegacyTokenPath, getAdditionalLegacyPaths } from './utils.js';\nimport { GaxiosError } from 'gaxios';\n\nexport class TokenManager {\n private oauth2Client: OAuth2Client;\n private tokenPath: string;\n\n constructor(oauth2Client: OAuth2Client) {\n this.oauth2Client = oauth2Client;\n this.tokenPath = getSecureTokenPath();\n this.setupTokenRefresh();\n }\n\n // Method to expose the token path\n public getTokenPath(): string {\n return this.tokenPath;\n }\n\n private async ensureTokenDirectoryExists(): Promise<void> {\n try {\n const dir = path.dirname(this.tokenPath);\n await fs.mkdir(dir, { recursive: true });\n } catch (error: unknown) {\n // Ignore errors if directory already exists, re-throw others\n if (error instanceof Error && 'code' in error && (error as any).code !== 'EEXIST') {\n console.error('Failed to create token directory:', error);\n throw error;\n }\n }\n }\n\n private setupTokenRefresh(): void {\n this.oauth2Client.on(\"tokens\", async (newTokens) => {\n try {\n await this.ensureTokenDirectoryExists();\n const currentTokens = JSON.parse(await fs.readFile(this.tokenPath, \"utf-8\"));\n const updatedTokens = {\n ...currentTokens,\n ...newTokens,\n refresh_token: newTokens.refresh_token || currentTokens.refresh_token,\n };\n await fs.writeFile(this.tokenPath, JSON.stringify(updatedTokens, null, 2), {\n mode: 0o600,\n });\n console.error(\"Tokens updated and saved\");\n } catch (error: unknown) {\n // Handle case where currentTokens might not exist yet\n if (error instanceof Error && 'code' in error && (error as any).code === 'ENOENT') { \n try {\n await fs.writeFile(this.tokenPath, JSON.stringify(newTokens, null, 2), { mode: 0o600 });\n console.error(\"New tokens saved\");\n } catch (writeError) {\n console.error(\"Error saving initial tokens:\", writeError);\n }\n } else {\n console.error(\"Error saving updated tokens:\", error);\n }\n }\n });\n }\n\n private async migrateLegacyTokens(): Promise<boolean> {\n // Check all possible legacy locations\n const legacyPaths = [getLegacyTokenPath(), ...getAdditionalLegacyPaths()];\n \n for (const legacyPath of legacyPaths) {\n try {\n // Check if legacy tokens exist\n if (!(await fs.access(legacyPath).then(() => true).catch(() => false))) {\n continue; // Try next location\n }\n\n // Read legacy tokens\n const legacyTokens = JSON.parse(await fs.readFile(legacyPath, \"utf-8\"));\n \n if (!legacyTokens || typeof legacyTokens !== \"object\") {\n console.error(\"Invalid legacy token format at\", legacyPath, \", skipping\");\n continue;\n }\n\n // Ensure new token directory exists\n await this.ensureTokenDirectoryExists();\n \n // Copy to new location\n await fs.writeFile(this.tokenPath, JSON.stringify(legacyTokens, null, 2), {\n mode: 0o600,\n });\n \n console.error(\"Migrated tokens from legacy location:\", legacyPath, \"to:\", this.tokenPath);\n \n // Optionally remove legacy file after successful migration\n try {\n await fs.unlink(legacyPath);\n console.error(\"Removed legacy token file\");\n } catch (unlinkErr) {\n console.error(\"Warning: Could not remove legacy token file:\", unlinkErr);\n }\n \n return true;\n } catch (error) {\n console.error(\"Error migrating legacy tokens from\", legacyPath, \":\", error);\n // Continue to next location\n }\n }\n \n return false; // No legacy tokens found or migrated\n }\n\n async loadSavedTokens(): Promise<boolean> {\n try {\n await this.ensureTokenDirectoryExists();\n \n // Check if current token file exists\n const tokenExists = await fs.access(this.tokenPath).then(() => true).catch(() => false);\n \n // If no current tokens, try to migrate from legacy location\n if (!tokenExists) {\n const migrated = await this.migrateLegacyTokens();\n if (!migrated) {\n console.error(\"No token file found at:\", this.tokenPath);\n return false;\n }\n }\n\n const tokens = JSON.parse(await fs.readFile(this.tokenPath, \"utf-8\"));\n\n if (!tokens || typeof tokens !== \"object\") {\n console.error(\"Invalid token format in file:\", this.tokenPath);\n return false;\n }\n\n this.oauth2Client.setCredentials(tokens);\n console.error('Tokens loaded and set on OAuth2Client:', {\n hasAccessToken: !!tokens.access_token,\n hasRefreshToken: !!tokens.refresh_token,\n tokenLength: tokens.access_token?.length,\n expiryDate: tokens.expiry_date,\n scope: tokens.scope\n });\n console.error('OAuth2Client after setCredentials:', {\n hasCredentials: !!this.oauth2Client.credentials,\n credentialsAccessToken: !!this.oauth2Client.credentials?.access_token\n });\n return true;\n } catch (error: unknown) {\n console.error(\"Error loading tokens:\", error);\n // Attempt to delete potentially corrupted token file\n if (error instanceof Error && 'code' in error && (error as any).code !== 'ENOENT') { \n try { \n await fs.unlink(this.tokenPath); \n console.error(\"Removed potentially corrupted token file\") \n } catch (_unlinkErr) { /* ignore */ }\n }\n return false;\n }\n }\n\n async refreshTokensIfNeeded(): Promise<boolean> {\n const expiryDate = this.oauth2Client.credentials.expiry_date;\n const isExpired = expiryDate\n ? Date.now() >= expiryDate - 5 * 60 * 1000 // 5 minute buffer\n : !this.oauth2Client.credentials.access_token; // No token means we need one\n\n if (isExpired && this.oauth2Client.credentials.refresh_token) {\n console.error(\"Auth token expired or nearing expiry, refreshing...\");\n try {\n const response = await this.oauth2Client.refreshAccessToken();\n const newTokens = response.credentials;\n\n if (!newTokens.access_token) {\n throw new Error(\"Received invalid tokens during refresh\");\n }\n // The 'tokens' event listener should handle saving\n this.oauth2Client.setCredentials(newTokens);\n console.error(\"Token refreshed successfully\");\n return true;\n } catch (refreshError) {\n if (refreshError instanceof GaxiosError && refreshError.response?.data?.error === 'invalid_grant') {\n console.error(\"Error refreshing auth token: Invalid grant. Token likely expired or revoked. Please re-authenticate.\");\n // Optionally clear the potentially invalid tokens here\n await this.clearTokens(); \n return false; // Indicate failure due to invalid grant\n } else {\n // Handle other refresh errors\n console.error(\"Error refreshing auth token:\", refreshError);\n return false;\n }\n }\n } else if (!this.oauth2Client.credentials.access_token && !this.oauth2Client.credentials.refresh_token) {\n console.error(\"No access or refresh token available. Please re-authenticate.\");\n return false;\n } else {\n // Token is valid or no refresh token available\n return true;\n }\n }\n\n async validateTokens(): Promise<boolean> {\n if (!this.oauth2Client.credentials || !this.oauth2Client.credentials.access_token) {\n // Try loading first if no credentials set\n if (!(await this.loadSavedTokens())) {\n return false; // No saved tokens to load\n }\n // Check again after loading\n if (!this.oauth2Client.credentials || !this.oauth2Client.credentials.access_token) {\n return false; // Still no token after loading\n }\n }\n return this.refreshTokensIfNeeded();\n }\n\n async saveTokens(tokens: Credentials): Promise<void> {\n try {\n await this.ensureTokenDirectoryExists();\n await fs.writeFile(this.tokenPath, JSON.stringify(tokens, null, 2), { mode: 0o600 });\n this.oauth2Client.setCredentials(tokens);\n console.error(\"Tokens saved successfully to:\", this.tokenPath);\n } catch (error: unknown) {\n console.error(\"Error saving tokens:\", error);\n throw error;\n }\n }\n\n async clearTokens(): Promise<void> {\n try {\n this.oauth2Client.setCredentials({}); // Clear in memory\n await fs.unlink(this.tokenPath);\n console.error(\"Tokens cleared successfully\");\n } catch (error: unknown) {\n if (error instanceof Error && 'code' in error && (error as any).code === 'ENOENT') {\n // File already gone, which is fine\n console.error(\"Token file already deleted\");\n } else {\n console.error(\"Error clearing tokens:\", error);\n // Don't re-throw, clearing is best-effort\n }\n }\n }\n}", "// ---------------------------------------------------------------------------\n// Shared OAuth scope constants & resolution\n// ---------------------------------------------------------------------------\n\nexport const SCOPE_ALIASES: Record<string, string> = {\n drive: 'https://www.googleapis.com/auth/drive',\n 'drive.file': 'https://www.googleapis.com/auth/drive.file',\n 'drive.readonly': 'https://www.googleapis.com/auth/drive.readonly',\n documents: 'https://www.googleapis.com/auth/documents',\n spreadsheets: 'https://www.googleapis.com/auth/spreadsheets',\n presentations: 'https://www.googleapis.com/auth/presentations',\n calendar: 'https://www.googleapis.com/auth/calendar',\n 'calendar.events': 'https://www.googleapis.com/auth/calendar.events',\n};\n\nexport const SCOPE_PRESETS: Record<string, string[]> = {\n readonly: ['drive.readonly'],\n 'content-editor': ['drive.file', 'documents', 'spreadsheets', 'presentations'],\n full: ['drive', 'documents', 'spreadsheets', 'presentations', 'calendar', 'calendar.events'],\n};\n\nexport const DEFAULT_SCOPES: readonly string[] = [\n 'drive', 'drive.file', 'drive.readonly',\n 'documents', 'spreadsheets', 'presentations',\n 'calendar', 'calendar.events',\n].map((s) => SCOPE_ALIASES[s]);\n\n/**\n * Resolve OAuth scopes from `GOOGLE_DRIVE_MCP_SCOPES` env var.\n * Accepts comma-separated aliases (e.g. \"drive,documents\") or full URLs.\n * Throws on unknown aliases so mis-configurations surface immediately.\n */\nexport function resolveOAuthScopes(): string[] {\n const raw = process.env.GOOGLE_DRIVE_MCP_SCOPES?.trim();\n if (!raw) return [...DEFAULT_SCOPES];\n\n const scopes = raw\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean)\n .map((s) => {\n if (SCOPE_ALIASES[s]) return SCOPE_ALIASES[s];\n if (s.startsWith('https://')) return s;\n const known = Object.keys(SCOPE_ALIASES).join(', ');\n throw new Error(\n `Unknown OAuth scope alias \"${s}\". Use a full URL (https://...) or one of: ${known}`\n );\n });\n\n if (scopes.length === 0) return [...DEFAULT_SCOPES];\n return [...new Set(scopes)];\n}\n", "// ---------------------------------------------------------------------------\n// External authentication modes: Service Account & pre-obtained OAuth tokens\n// ---------------------------------------------------------------------------\n\nimport { OAuth2Client } from 'google-auth-library';\nimport { GoogleAuth } from 'google-auth-library';\nimport { DEFAULT_SCOPES } from './scopes.js';\n\n// ---------------------------------------------------------------------------\n// Service Account mode\n// ---------------------------------------------------------------------------\n\n/** True when `GOOGLE_APPLICATION_CREDENTIALS` is set (standard Google convention). */\nexport function isServiceAccountMode(): boolean {\n return !!process.env.GOOGLE_APPLICATION_CREDENTIALS;\n}\n\n/**\n * Create an authorized client from a service account JSON key file.\n * `GoogleAuth` handles JWT signing and token refresh automatically.\n */\nexport async function createServiceAccountAuth(): Promise<any> {\n const keyFile = process.env.GOOGLE_APPLICATION_CREDENTIALS!;\n console.error(`Using service account credentials from ${keyFile}`);\n\n const auth = new GoogleAuth({\n keyFile,\n scopes: [...DEFAULT_SCOPES],\n });\n\n const client = await auth.getClient();\n console.error('Service account authentication successful');\n return client;\n}\n\n// ---------------------------------------------------------------------------\n// External OAuth Token mode\n// ---------------------------------------------------------------------------\n\n/** True when `GOOGLE_DRIVE_MCP_ACCESS_TOKEN` is set. */\nexport function isExternalTokenMode(): boolean {\n return !!process.env.GOOGLE_DRIVE_MCP_ACCESS_TOKEN;\n}\n\n/**\n * Validate that the env-var combination makes sense.\n * Throws with an actionable message on mis-configuration.\n */\nexport function validateExternalTokenConfig(): void {\n const accessToken = process.env.GOOGLE_DRIVE_MCP_ACCESS_TOKEN?.trim();\n if (!accessToken) {\n throw new Error(\n 'GOOGLE_DRIVE_MCP_ACCESS_TOKEN is set but empty. Provide a valid OAuth access token.'\n );\n }\n\n const refreshToken = process.env.GOOGLE_DRIVE_MCP_REFRESH_TOKEN?.trim();\n const clientId = process.env.GOOGLE_DRIVE_MCP_CLIENT_ID?.trim();\n const clientSecret = process.env.GOOGLE_DRIVE_MCP_CLIENT_SECRET?.trim();\n\n if (refreshToken) {\n if (!clientId || !clientSecret) {\n throw new Error(\n 'GOOGLE_DRIVE_MCP_REFRESH_TOKEN is set but GOOGLE_DRIVE_MCP_CLIENT_ID and/or ' +\n 'GOOGLE_DRIVE_MCP_CLIENT_SECRET are missing. All three are required for automatic token refresh.'\n );\n }\n }\n\n // Warn about partial client credential sets (one without the other)\n if ((clientId && !clientSecret) || (!clientId && clientSecret)) {\n throw new Error(\n 'Both GOOGLE_DRIVE_MCP_CLIENT_ID and GOOGLE_DRIVE_MCP_CLIENT_SECRET must be provided together.'\n );\n }\n}\n\n/**\n * Create an OAuth2Client pre-loaded with externally-obtained credentials.\n * When a refresh token + client credentials are provided, the client will\n * auto-refresh transparently.\n */\nexport function createExternalOAuth2Client(): OAuth2Client {\n const accessToken = process.env.GOOGLE_DRIVE_MCP_ACCESS_TOKEN!.trim();\n const refreshToken = process.env.GOOGLE_DRIVE_MCP_REFRESH_TOKEN?.trim();\n const clientId = process.env.GOOGLE_DRIVE_MCP_CLIENT_ID?.trim();\n const clientSecret = process.env.GOOGLE_DRIVE_MCP_CLIENT_SECRET?.trim();\n\n const oauth2Client = new OAuth2Client(clientId, clientSecret);\n\n oauth2Client.setCredentials({\n access_token: accessToken,\n refresh_token: refreshToken || undefined,\n });\n\n if (!refreshToken) {\n console.error(\n 'Warning: No refresh token provided. The access token will not auto-refresh when it expires.'\n );\n } else {\n console.error('External OAuth tokens configured with auto-refresh support.');\n }\n\n return oauth2Client;\n}\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';\nimport {\n isServiceAccountMode, createServiceAccountAuth,\n isExternalTokenMode, validateExternalTokenConfig,\n createExternalOAuth2Client,\n} from './auth/externalAuth.js';\n\nexport { TokenManager } from './auth/tokenManager.js';\nexport { initializeOAuth2Client } from './auth/client.js';\nexport { AuthServer } from './auth/server.js';\nexport { SCOPE_ALIASES, SCOPE_PRESETS, DEFAULT_SCOPES, resolveOAuthScopes } from './auth/scopes.js';\nexport {\n isServiceAccountMode, createServiceAccountAuth,\n isExternalTokenMode, validateExternalTokenConfig,\n createExternalOAuth2Client,\n} from './auth/externalAuth.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 // Priority 1: Service account\n if (isServiceAccountMode()) {\n return await createServiceAccountAuth();\n }\n\n // Priority 2: External OAuth tokens\n if (isExternalTokenMode()) {\n validateExternalTokenConfig();\n return createExternalOAuth2Client();\n }\n\n // Priority 3: Existing local OAuth flow\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(() => {\n if (authServer.authCompletedSuccessfully) {\n clearInterval(intervalId);\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}", "// -----------------------------------------------------------------------------\n// Pure utility functions extracted from index.ts for testability\n// -----------------------------------------------------------------------------\n\n// ---------------------------------------------------------------------------\n// Calendar helpers\n// ---------------------------------------------------------------------------\n\nexport interface CalendarEventOverrides {\n summary?: string;\n description?: string;\n location?: string;\n start?: any;\n end?: any;\n attendees?: string[];\n [key: string]: any;\n}\n\n/**\n * Build the event resource for an updateCalendarEvent call by merging user\n * overrides onto the existing event while excluding read-only fields.\n *\n * Rules:\n * - User overrides win when explicitly provided (even if empty string / empty array)\n * - Existing values are preserved when the override is `undefined`\n * - Attendees are mapped from `string[]` \u2192 `{email}[]`\n * - Only mutable fields are included; read-only fields (id, kind, etag, htmlLink,\n * iCalUID, creator, organizer, sequence, \u2026) are never forwarded\n */\nexport function buildCalendarEventUpdate(existing: any, overrides: CalendarEventOverrides): any {\n return {\n summary: overrides.summary !== undefined ? overrides.summary : existing.summary,\n description: overrides.description !== undefined ? overrides.description : existing.description,\n location: overrides.location !== undefined ? overrides.location : existing.location,\n start: overrides.start || existing.start,\n end: overrides.end || existing.end,\n attendees: overrides.attendees !== undefined\n ? overrides.attendees.map((email: string) => ({ email }))\n : existing.attendees,\n recurrence: existing.recurrence,\n visibility: existing.visibility,\n reminders: existing.reminders,\n };\n}\n\n/**\n * Get file extension from a filename (lowercase).\n */\nexport function getExtensionFromFilename(filename: string): string {\n return filename.split('.').pop()?.toLowerCase() || '';\n}\n\nexport const TEXT_MIME_TYPES: Record<string, string> = {\n txt: 'text/plain',\n md: 'text/markdown',\n};\n\n/**\n * Get the MIME type for a text file from its filename.\n * Falls back to 'text/plain' for unknown extensions.\n */\nexport function getMimeTypeFromFilename(filename: string): string {\n const ext = getExtensionFromFilename(filename);\n return TEXT_MIME_TYPES[ext] || 'text/plain';\n}\n\n/**\n * Escape a string for use in a Google Drive API query.\n * Escapes backslashes and single quotes.\n */\nexport function escapeDriveQuery(value: string): string {\n return value.replace(/\\\\/g, \"\\\\\\\\\").replace(/'/g, \"\\\\'\");\n}\n\n/**\n * Parse a Sheets A1 range reference (e.g. \"'My Sheet'!A1:B2\") into its\n * sheet name and cell range components.\n *\n * - Strips surrounding single quotes from the sheet name\n * - Defaults to 'Sheet1' when no sheet prefix is present\n */\nexport function parseA1Range(range: string): { sheetName: string; cellRange: string } {\n if (range.includes('!')) {\n const sheetName = range.split('!')[0].replace(/^'+|'+$/g, '');\n const cellRange = range.split('!')[1];\n return { sheetName, cellRange };\n }\n return { sheetName: 'Sheet1', cellRange: range };\n}\n\n/**\n * Convert column letters to a zero-based index (A=0, B=1, ... Z=25, AA=26).\n */\nexport function colToIndex(col: string): number {\n let num = 0;\n for (let i = 0; i < col.length; i++) {\n num = num * 26 + (col.charCodeAt(i) - 'A'.charCodeAt(0) + 1);\n }\n return num - 1;\n}\n\nexport interface GridRange {\n sheetId: number;\n startColumnIndex?: number;\n startRowIndex?: number;\n endColumnIndex?: number;\n endRowIndex?: number;\n}\n\n/**\n * Convert an A1 notation string (e.g. \"A1:C5\") into a Sheets GridRange object.\n * Supports ranges, single cells, full-row (\"1:3\"), and full-column (\"A:C\") notation.\n */\nexport function convertA1ToGridRange(a1Notation: string, sheetId: number): GridRange {\n const rangeRegex = /^([A-Z]*)([0-9]*)(:([A-Z]*)([0-9]*))?$/;\n const match = a1Notation.match(rangeRegex);\n\n if (!match) {\n throw new Error(`Invalid A1 notation: ${a1Notation}`);\n }\n\n const [, startCol, startRow, , endCol, endRow] = match;\n\n const gridRange: GridRange = { sheetId };\n\n if (startCol) gridRange.startColumnIndex = colToIndex(startCol);\n if (startRow) gridRange.startRowIndex = parseInt(startRow) - 1;\n\n if (endCol) {\n gridRange.endColumnIndex = colToIndex(endCol) + 1;\n } else if (startCol && !endCol) {\n gridRange.endColumnIndex = gridRange.startColumnIndex! + 1;\n }\n\n if (endRow) {\n gridRange.endRowIndex = parseInt(endRow);\n } else if (startRow && !endRow) {\n gridRange.endRowIndex = gridRange.startRowIndex! + 1;\n }\n\n return gridRange;\n}\n", "import type { drive_v3, calendar_v3 } from 'googleapis';\nimport type { google as GoogleApisType } from 'googleapis';\n\nexport interface ToolResult {\n [key: string]: unknown;\n content: Array<{ type: string; text: string }>;\n isError?: boolean;\n}\n\nexport interface ToolDefinition {\n name: string;\n description: string;\n inputSchema: Record<string, unknown>;\n}\n\nexport interface ToolContext {\n authClient: any;\n google: typeof GoogleApisType;\n getDrive: () => drive_v3.Drive;\n getCalendar: () => calendar_v3.Calendar;\n log: (message: string, data?: any) => void;\n resolvePath: (pathStr: string) => Promise<string>;\n resolveFolderId: (input: string | undefined) => Promise<string>;\n checkFileExists: (name: string, parentFolderId?: string) => Promise<string | null>;\n validateTextFileExtension: (name: string) => void;\n}\n\nexport function errorResponse(message: string): ToolResult {\n return { content: [{ type: \"text\", text: `Error: ${message}` }], isError: true };\n}\n", "import { z } from 'zod';\nimport type { drive_v3 } from 'googleapis';\nimport { existsSync, statSync, createReadStream } from 'fs';\nimport { mkdtemp, readFile, writeFile, rm } from 'fs/promises';\nimport { tmpdir } from 'os';\nimport { basename, extname, join } from 'path';\nimport { PDFDocument } from 'pdf-lib';\nimport type { ToolDefinition, ToolContext, ToolResult } from '../types.js';\nimport { errorResponse } from '../types.js';\nimport { escapeDriveQuery, getMimeTypeFromFilename, TEXT_MIME_TYPES } from '../utils.js';\nimport { downloadDriveFile, GOOGLE_WORKSPACE_EXPORT_FORMATS } from '../download-file.js';\nimport { getSecureTokenPath } from '../auth/utils.js';\nimport { SCOPE_ALIASES, SCOPE_PRESETS, resolveOAuthScopes } from '../auth/scopes.js';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst FOLDER_MIME_TYPE = 'application/vnd.google-apps.folder';\nconst SHORTCUT_MIME_TYPE = 'application/vnd.google-apps.shortcut';\n\n// MIME types for binary file uploads (extension \u2192 MIME)\nconst BINARY_MIME_TYPES: Record<string, string> = {\n jpg: 'image/jpeg', jpeg: 'image/jpeg', png: 'image/png', gif: 'image/gif',\n webp: 'image/webp', svg: 'image/svg+xml', bmp: 'image/bmp', ico: 'image/x-icon',\n mp3: 'audio/mpeg', wav: 'audio/wav', ogg: 'audio/ogg', m4a: 'audio/mp4',\n aac: 'audio/aac', flac: 'audio/flac', opus: 'audio/opus',\n mp4: 'video/mp4', webm: 'video/webm', avi: 'video/x-msvideo', mov: 'video/quicktime',\n mkv: 'video/x-matroska', '3gp': 'video/3gpp',\n pdf: 'application/pdf', zip: 'application/zip', gz: 'application/gzip',\n tar: 'application/x-tar', json: 'application/json', xml: 'application/xml',\n csv: 'text/csv', html: 'text/html', css: 'text/css', js: 'application/javascript',\n doc: 'application/msword', docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n xls: 'application/vnd.ms-excel', xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n ppt: 'application/vnd.ms-powerpoint', pptx: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',\n};\n\n// ---------------------------------------------------------------------------\n// Zod schemas\n// ---------------------------------------------------------------------------\n\nconst SearchSchema = z.object({\n query: z.string().min(1, \"Search query is required\"),\n pageSize: z.number().int().min(1).max(100).optional(),\n pageToken: z.string().optional(),\n rawQuery: z.boolean().optional(),\n});\n\nconst CreateTextFileSchema = z.object({\n name: z.string().min(1, \"File name is required\"),\n content: z.string(),\n parentFolderId: z.string().optional()\n});\n\nconst UpdateTextFileSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\"),\n content: z.string(),\n name: z.string().optional()\n});\n\nconst CreateFolderSchema = z.object({\n name: z.string().min(1, \"Folder name is required\"),\n parent: z.string().optional()\n});\n\nconst ListFolderSchema = z.object({\n folderId: z.string().optional(),\n pageSize: z.number().int().min(1).max(100).optional(),\n pageToken: z.string().optional()\n});\n\nconst ListSharedDrivesSchema = z.object({\n pageSize: z.number().int().min(1).max(100).optional(),\n pageToken: z.string().optional()\n});\n\nconst DeleteItemSchema = z.object({\n itemId: z.string().min(1, \"Item ID is required\")\n});\n\nconst RenameItemSchema = z.object({\n itemId: z.string().min(1, \"Item ID is required\"),\n newName: z.string().min(1, \"New name is required\")\n});\n\nconst MoveItemSchema = z.object({\n itemId: z.string().min(1, \"Item ID is required\"),\n destinationFolderId: z.string().optional()\n});\n\nconst CopyFileSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\"),\n newName: z.string().optional(),\n parentFolderId: z.string().optional()\n});\n\nconst CreateShortcutSchema = z.object({\n targetFileId: z.string().min(1, \"Target file ID is required\"),\n parentFolderId: z.string().optional(),\n shortcutName: z.string().optional()\n});\n\nconst LockFileSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\"),\n reason: z.string().optional(),\n ownerRestricted: z.boolean().optional()\n});\n\nconst UnlockFileSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\")\n});\n\nconst UploadFileSchema = z.object({\n localPath: z.string().min(1, \"Local file path is required\"),\n name: z.string().optional(),\n parentFolderId: z.string().optional(),\n mimeType: z.string().optional(),\n convertToGoogleFormat: z.boolean().optional()\n});\n\nconst DownloadFileSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\"),\n localPath: z.string().min(1, \"Local file path is required\"),\n exportMimeType: z.string().optional(),\n overwrite: z.boolean().optional().default(false),\n});\n\nconst ListPermissionsSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\"),\n});\n\nconst AddPermissionSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\"),\n emailAddress: z.string().email(\"Valid email is required\"),\n role: z.enum([\"owner\", \"organizer\", \"fileOrganizer\", \"writer\", \"commenter\", \"reader\"]).default(\"reader\"),\n type: z.enum([\"user\", \"group\", \"domain\", \"anyone\"]).default(\"user\"),\n sendNotificationEmail: z.boolean().optional().default(false),\n});\n\nconst UpdatePermissionSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\"),\n permissionId: z.string().min(1, \"Permission ID is required\"),\n role: z.enum([\"owner\", \"organizer\", \"fileOrganizer\", \"writer\", \"commenter\", \"reader\"]),\n});\n\nconst RemovePermissionSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\"),\n permissionId: z.string().optional(),\n emailAddress: z.string().email(\"Valid email is required\").optional(),\n}).superRefine((data, ctx) => {\n if (!data.permissionId && !data.emailAddress) {\n ctx.addIssue({ code: z.ZodIssueCode.custom, message: \"Either permissionId or emailAddress is required\" });\n }\n});\n\nconst ShareFileSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\"),\n emailAddress: z.string().email(\"Valid email is required\"),\n role: z.enum([\"writer\", \"commenter\", \"reader\"]).default(\"reader\"),\n sendNotificationEmail: z.boolean().optional().default(true),\n});\n\nconst ConvertPdfToGoogleDocSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\"),\n newName: z.string().optional(),\n parentFolderId: z.string().optional(),\n});\n\nconst BulkConvertFolderPdfsSchema = z.object({\n folderId: z.string().min(1, \"Folder ID is required\"),\n maxResults: z.number().int().min(1).max(200).optional().default(100),\n continueOnError: z.boolean().optional().default(true),\n});\n\nconst UploadPdfWithSplitSchema = z.object({\n localPath: z.string().min(1, \"Local file path is required\"),\n split: z.boolean().optional().default(false),\n maxPagesPerChunk: z.number().int().min(1).max(500).optional(),\n parentFolderId: z.string().optional(),\n namePrefix: z.string().optional(),\n});\n\nasync function splitPdfIntoChunkFiles(localPath: string, maxPagesPerChunk: number): Promise<{ tempDir: string; files: string[] }> {\n const sourceBytes = await readFile(localPath);\n const source = await PDFDocument.load(sourceBytes);\n const pageCount = source.getPageCount();\n\n if (pageCount === 0) {\n throw new Error('PDF contains no pages.');\n }\n\n const tempDir = await mkdtemp(join(tmpdir(), 'gdrive-mcp-split-'));\n const files: string[] = [];\n\n for (let start = 0, part = 1; start < pageCount; start += maxPagesPerChunk, part++) {\n const end = Math.min(start + maxPagesPerChunk, pageCount);\n const chunkDoc = await PDFDocument.create();\n const pages = await chunkDoc.copyPages(source, Array.from({ length: end - start }, (_, i) => start + i));\n for (const page of pages) chunkDoc.addPage(page);\n\n const chunkBytes = await chunkDoc.save();\n const chunkPath = join(tempDir, `part-${part}.pdf`);\n await writeFile(chunkPath, chunkBytes);\n files.push(chunkPath);\n }\n\n return { tempDir, files };\n}\n\nconst GetRevisionsSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\"),\n pageSize: z.number().int().min(1).max(200).optional().default(50),\n pageToken: z.string().optional(),\n});\n\nconst RestoreRevisionSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\"),\n revisionId: z.string().min(1, \"Revision ID is required\"),\n confirm: z.boolean().optional().default(false),\n});\n\nconst AuthTestFileAccessSchema = z.object({\n fileId: z.string().optional(),\n});\n\nfunction getGrantedScopesFromAuthClient(ctx: ToolContext): string[] {\n const scopeRaw = ctx.authClient?.credentials?.scope;\n if (!scopeRaw || typeof scopeRaw !== 'string') return [];\n return [...new Set(scopeRaw.split(' ').map((s: string) => s.trim()).filter(Boolean))];\n}\n\nfunction resolveScopeStatus(ctx: ToolContext): { requestedScopes: string[]; grantedScopes: string[]; missingScopes: string[] } {\n const requestedScopes = resolveOAuthScopes();\n const grantedScopes = getGrantedScopesFromAuthClient(ctx);\n const missingScopes = requestedScopes.filter((s) => !grantedScopes.includes(s));\n return { requestedScopes, grantedScopes, missingScopes };\n}\n\n// ---------------------------------------------------------------------------\n// Tool definitions\n// ---------------------------------------------------------------------------\n\nexport const toolDefinitions: ToolDefinition[] = [\n {\n name: \"search\",\n description: \"Search for files in Google Drive. Set rawQuery=true to pass a raw Google Drive API query supporting operators like modifiedTime, createdTime, mimeType, name contains, etc.\",\n inputSchema: {\n type: \"object\",\n properties: {\n query: { type: \"string\", description: \"Search query. When rawQuery=true, this is passed directly to the Google Drive API as the q parameter.\" },\n pageSize: { type: \"number\", description: \"Results per page (default 50, max 100)\" },\n pageToken: { type: \"string\", description: \"Token for next page of results\" },\n rawQuery: { type: \"boolean\", description: \"If true, pass query directly to Google Drive API without wrapping in fullText contains. Enables date filters, mimeType filters, etc.\" },\n },\n required: [\"query\"],\n },\n },\n {\n name: \"createTextFile\",\n description: \"Create a new text or markdown file\",\n inputSchema: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"File name (.txt or .md)\" },\n content: { type: \"string\", description: \"File content\" },\n parentFolderId: { type: \"string\", description: \"Parent folder ID\" }\n },\n required: [\"name\", \"content\"]\n }\n },\n {\n name: \"updateTextFile\",\n description: \"Update an existing text or markdown file\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"ID of the file to update\" },\n content: { type: \"string\", description: \"New file content\" },\n name: { type: \"string\", description: \"New name (.txt or .md)\" }\n },\n required: [\"fileId\", \"content\"]\n }\n },\n {\n name: \"createFolder\",\n description: \"Create a new folder in Google Drive\",\n inputSchema: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"Folder name\" },\n parent: { type: \"string\", description: \"Parent folder ID or path\" }\n },\n required: [\"name\"]\n }\n },\n {\n name: \"listFolder\",\n description: \"List contents of a folder (defaults to root)\",\n inputSchema: {\n type: \"object\",\n properties: {\n folderId: { type: \"string\", description: \"Folder ID\" },\n pageSize: { type: \"number\", description: \"Items to return (default 50, max 100)\" },\n pageToken: { type: \"string\", description: \"Token for next page\" }\n }\n }\n },\n {\n name: \"listSharedDrives\",\n description: \"List available Google Shared Drives\",\n inputSchema: {\n type: \"object\",\n properties: {\n pageSize: { type: \"number\", description: \"Drives to return (default 50, max 100)\" },\n pageToken: { type: \"string\", description: \"Token for next page\" }\n }\n }\n },\n {\n name: \"deleteItem\",\n description: \"Move a file or folder to trash (can be restored from Google Drive trash)\",\n inputSchema: {\n type: \"object\",\n properties: {\n itemId: { type: \"string\", description: \"ID of the item to delete\" }\n },\n required: [\"itemId\"]\n }\n },\n {\n name: \"renameItem\",\n description: \"Rename a file or folder\",\n inputSchema: {\n type: \"object\",\n properties: {\n itemId: { type: \"string\", description: \"ID of the item to rename\" },\n newName: { type: \"string\", description: \"New name\" }\n },\n required: [\"itemId\", \"newName\"]\n }\n },\n {\n name: \"moveItem\",\n description: \"Move a file or folder\",\n inputSchema: {\n type: \"object\",\n properties: {\n itemId: { type: \"string\", description: \"ID of the item to move\" },\n destinationFolderId: { type: \"string\", description: \"Destination folder ID\" }\n },\n required: [\"itemId\"]\n }\n },\n {\n name: \"copyFile\",\n description: \"Creates a copy of a Google Drive file or document\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"ID of the file to copy\" },\n newName: { type: \"string\", description: \"Name for the copied file. If not provided, will use 'Copy of [original name]'\" },\n parentFolderId: { type: \"string\", description: \"ID or path of the destination folder (defaults to same folder as original)\" }\n },\n required: [\"fileId\"]\n }\n },\n {\n name: \"uploadFile\",\n description: \"Upload a local file (any type: image, audio, video, PDF, etc.) to Google Drive\",\n inputSchema: {\n type: \"object\",\n properties: {\n localPath: { type: \"string\", description: \"Absolute path to the local file to upload\" },\n name: { type: \"string\", description: \"File name in Drive (defaults to local filename)\" },\n parentFolderId: { type: \"string\", description: \"Parent folder ID or path (e.g., '/Work/Projects'). Creates folders if needed. Defaults to root.\" },\n mimeType: { type: \"string\", description: \"MIME type (auto-detected from extension if omitted)\" },\n convertToGoogleFormat: { type: \"boolean\", description: \"Convert uploaded file to Google Workspace format (e.g., .docx to Google Doc, .xlsx to Google Sheet, .pptx to Google Slides). Defaults to false.\" }\n },\n required: [\"localPath\"]\n }\n },\n {\n name: \"downloadFile\",\n description: \"Download a Google Drive file to a local path. For Google Workspace files (Docs, Sheets, Slides, Drawings), exports to the specified format. For regular files, downloads as-is. Streams directly to disk.\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"Google Drive file ID\" },\n localPath: { type: \"string\", description: \"Absolute local path to save the file (must start with /). Can be a directory (filename auto-resolved from Drive metadata) or a full file path. Path is normalized before use.\" },\n exportMimeType: {\n type: \"string\",\n description: \"For Google Workspace files: MIME type to export as (e.g., 'application/pdf', 'text/csv'). Auto-detected from file extension if omitted. Ignored for non-Workspace files.\"\n },\n overwrite: {\n type: \"boolean\",\n description: \"Whether to overwrite if file already exists at localPath. When false (default), returns an error instead of replacing the file.\"\n }\n },\n required: [\"fileId\", \"localPath\"]\n }\n },\n {\n name: \"listPermissions\",\n description: \"List sharing permissions for a file\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"Google Drive file ID\" }\n },\n required: [\"fileId\"]\n }\n },\n {\n name: \"addPermission\",\n description: \"Add a sharing permission to a file\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"Google Drive file ID\" },\n emailAddress: { type: \"string\", description: \"Target user/group email\" },\n role: { type: \"string\", enum: [\"owner\", \"organizer\", \"fileOrganizer\", \"writer\", \"commenter\", \"reader\"], description: \"Permission role\" },\n type: { type: \"string\", enum: [\"user\", \"group\", \"domain\", \"anyone\"], description: \"Principal type\" },\n sendNotificationEmail: { type: \"boolean\", description: \"Send notification email\" }\n },\n required: [\"fileId\", \"emailAddress\"]\n }\n },\n {\n name: \"updatePermission\",\n description: \"Update an existing permission role\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"Google Drive file ID\" },\n permissionId: { type: \"string\", description: \"Permission ID\" },\n role: { type: \"string\", enum: [\"owner\", \"organizer\", \"fileOrganizer\", \"writer\", \"commenter\", \"reader\"], description: \"New role\" }\n },\n required: [\"fileId\", \"permissionId\", \"role\"]\n }\n },\n {\n name: \"removePermission\",\n description: \"Remove a permission from a file (by permissionId or emailAddress)\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"Google Drive file ID\" },\n permissionId: { type: \"string\", description: \"Permission ID\" },\n emailAddress: { type: \"string\", description: \"User email (alternative to permissionId)\" }\n },\n required: [\"fileId\"]\n }\n },\n {\n name: \"shareFile\",\n description: \"Convenience wrapper to share a file with a user email\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"Google Drive file ID\" },\n emailAddress: { type: \"string\", description: \"User email\" },\n role: { type: \"string\", enum: [\"writer\", \"commenter\", \"reader\"], description: \"Access role\" },\n sendNotificationEmail: { type: \"boolean\", description: \"Send notification email\" }\n },\n required: [\"fileId\", \"emailAddress\"]\n }\n },\n {\n name: \"convertPdfToGoogleDoc\",\n description: \"Convert an existing PDF in Drive into an editable Google Doc\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"PDF file ID in Google Drive\" },\n newName: { type: \"string\", description: \"Optional name for converted Doc\" },\n parentFolderId: { type: \"string\", description: \"Optional destination folder ID\" }\n },\n required: [\"fileId\"]\n }\n },\n {\n name: \"bulkConvertFolderPdfs\",\n description: \"Convert all PDFs in a folder into Google Docs and return per-file results\",\n inputSchema: {\n type: \"object\",\n properties: {\n folderId: { type: \"string\", description: \"Folder ID containing PDFs\" },\n maxResults: { type: \"number\", description: \"Maximum PDFs to process (1-200, default: 100)\" },\n continueOnError: { type: \"boolean\", description: \"Continue conversion when one file fails (default: true)\" }\n },\n required: [\"folderId\"]\n }\n },\n {\n name: \"uploadPdfWithSplit\",\n description: \"Upload PDF and optionally split into chunked parts (metadata split plan for now)\",\n inputSchema: {\n type: \"object\",\n properties: {\n localPath: { type: \"string\", description: \"Absolute path to local PDF\" },\n split: { type: \"boolean\", description: \"Enable split mode\" },\n maxPagesPerChunk: { type: \"number\", description: \"Target max pages per chunk (advisory metadata)\" },\n parentFolderId: { type: \"string\", description: \"Optional destination folder ID\" },\n namePrefix: { type: \"string\", description: \"Optional output name prefix\" }\n },\n required: [\"localPath\"]\n }\n },\n {\n name: \"getRevisions\",\n description: \"List revisions for a file\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"Google Drive file ID\" },\n pageSize: { type: \"number\", description: \"Max revisions to return (default 50, max 200)\" },\n pageToken: { type: \"string\", description: \"Page token for pagination\" }\n },\n required: [\"fileId\"]\n }\n },\n {\n name: \"restoreRevision\",\n description: \"Restore a file to a selected revision (creates a new head revision). Note: workspace files (Docs, Sheets, Slides) are restored via export/import and may lose some formatting.\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"Google Drive file ID\" },\n revisionId: { type: \"string\", description: \"Revision ID to restore\" },\n confirm: { type: \"boolean\", description: \"Safety flag. Must be true to execute restore.\" }\n },\n required: [\"fileId\", \"revisionId\"]\n }\n },\n {\n name: \"authGetStatus\",\n description: \"Show authentication/token status and scope diagnostics\",\n inputSchema: { type: \"object\", properties: {} }\n },\n {\n name: \"authListScopes\",\n description: \"List configured/requested scopes and currently granted scopes\",\n inputSchema: { type: \"object\", properties: {} }\n },\n {\n name: \"authTestFileAccess\",\n description: \"Run auth diagnostics against Drive API/file access\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"Optional file ID for targeted access check\" }\n }\n }\n },\n {\n name: \"createShortcut\",\n description: \"Create a shortcut (link) to a file or folder in Google Drive. Useful for referencing the same document from multiple locations without duplicating it.\",\n inputSchema: {\n type: \"object\",\n properties: {\n targetFileId: {\n type: \"string\",\n description: \"The file or folder ID (not a path) to create a shortcut to\"\n },\n parentFolderId: {\n type: \"string\",\n description: \"ID or path of the folder where the shortcut will be created\"\n },\n shortcutName: {\n type: \"string\",\n description: \"Custom name for the shortcut (defaults to original file name)\"\n }\n },\n required: [\"targetFileId\"]\n }\n },\n {\n name: \"lockFile\",\n description: \"Lock a file to prevent editing by setting content restrictions. The file remains readable but cannot be modified until unlocked.\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: {\n type: \"string\",\n description: \"ID of the file to lock\"\n },\n reason: {\n type: \"string\",\n description: \"Reason for locking the file (shown to users who try to edit)\"\n },\n ownerRestricted: {\n type: \"boolean\",\n description: \"If true, only the file owner can unlock the file (default: false)\"\n }\n },\n required: [\"fileId\"]\n }\n },\n {\n name: \"unlockFile\",\n description: \"Unlock a previously locked file by removing content restrictions, restoring full edit access.\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: {\n type: \"string\",\n description: \"ID of the file to unlock\"\n }\n },\n required: [\"fileId\"]\n }\n },\n];\n\n// ---------------------------------------------------------------------------\n// Handler\n// ---------------------------------------------------------------------------\n\nexport async function handleTool(\n toolName: string,\n args: Record<string, unknown>,\n ctx: ToolContext,\n): Promise<ToolResult | null> {\n switch (toolName) {\n\n case \"search\": {\n const validation = SearchSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const { query: userQuery, pageSize, pageToken, rawQuery } = validation.data;\n\n let formattedQuery: string;\n if (rawQuery) {\n // Use query directly; auto-append trashed guard unless user already includes it\n formattedQuery = /\\btrashed\\s*=/.test(userQuery)\n ? userQuery\n : `${userQuery} and trashed = false`;\n } else {\n const escapedQuery = escapeDriveQuery(userQuery);\n formattedQuery = `fullText contains '${escapedQuery}' and trashed = false`;\n }\n\n const res = await ctx.getDrive().files.list({\n q: formattedQuery,\n pageSize: Math.min(pageSize || 50, 100),\n pageToken: pageToken,\n fields: \"nextPageToken, files(id, name, mimeType, createdTime, modifiedTime, size, parents)\",\n corpora: \"allDrives\",\n includeItemsFromAllDrives: true,\n supportsAllDrives: true\n });\n\n // Resolve folder paths from parent IDs (with dedup for concurrent lookups)\n const pathCache: Record<string, Promise<string>> = {};\n function resolveParentPath(folderId: string, depth = 0): Promise<string> {\n if (depth >= 10) return Promise.resolve(folderId);\n if (folderId in pathCache) return pathCache[folderId];\n const promise = (async () => {\n try {\n const folderRes = await ctx.getDrive().files.get({\n fileId: folderId,\n fields: \"name, parents\",\n supportsAllDrives: true,\n });\n const name = folderRes.data.name || folderId;\n const parents = folderRes.data.parents;\n if (parents && parents.length > 0 && parents[0] !== folderId) {\n const parentPath = await resolveParentPath(parents[0], depth + 1);\n return `${parentPath}/${name}`;\n }\n return name;\n } catch {\n return folderId;\n }\n })();\n pathCache[folderId] = promise;\n return promise;\n }\n\n const files = res.data.files || [];\n const fileLines = await Promise.all(\n files.map(async (f: drive_v3.Schema$File) => {\n let folderPath = '';\n if (f.parents && f.parents.length > 0) {\n folderPath = await resolveParentPath(f.parents[0]);\n }\n return `${f.name} (${f.mimeType}) [id: ${f.id}, path: ${folderPath || '/'}] [created: ${f.createdTime || 'N/A'}, modified: ${f.modifiedTime || 'N/A'}]`;\n }),\n );\n\n ctx.log('Search results', { query: userQuery, rawQuery: !!rawQuery, resultCount: files.length });\n\n let response = `Found ${files.length} files:\\n${fileLines.join(\"\\n\")}`;\n if (res.data.nextPageToken) {\n response += `\\n\\nMore results available. Use pageToken: ${res.data.nextPageToken}`;\n }\n\n return {\n content: [{ type: \"text\", text: response }],\n isError: false,\n };\n }\n\n case \"createTextFile\": {\n const validation = CreateTextFileSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const data = validation.data;\n\n ctx.validateTextFileExtension(data.name);\n const parentFolderId = await ctx.resolveFolderId(data.parentFolderId);\n\n // Check if file already exists\n const existingFileId = await ctx.checkFileExists(data.name, parentFolderId);\n if (existingFileId) {\n return errorResponse(\n `A file named \"${data.name}\" already exists in this location. ` +\n `To update it, use updateTextFile with fileId: ${existingFileId}`\n );\n }\n\n const fileMetadata = {\n name: data.name,\n mimeType: getMimeTypeFromFilename(data.name),\n parents: [parentFolderId]\n };\n\n const file = await ctx.getDrive().files.create({\n requestBody: fileMetadata,\n media: {\n mimeType: fileMetadata.mimeType,\n body: data.content,\n },\n supportsAllDrives: true\n });\n\n ctx.log('File created successfully', { fileId: file.data?.id });\n return {\n content: [{\n type: \"text\",\n text: `Created file: ${file.data?.name || data.name}\\nID: ${file.data?.id || 'unknown'}`\n }],\n isError: false\n };\n }\n\n case \"updateTextFile\": {\n const validation = UpdateTextFileSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const data = validation.data;\n\n // Check file MIME type\n const existingFile = await ctx.getDrive().files.get({\n fileId: data.fileId,\n fields: 'mimeType, name, parents',\n supportsAllDrives: true\n });\n\n const currentMimeType = existingFile.data.mimeType || 'text/plain';\n if (!Object.values(TEXT_MIME_TYPES).includes(currentMimeType)) {\n return errorResponse(\"File is not a text or markdown file.\");\n }\n\n const updateMetadata: { name?: string; mimeType?: string } = {};\n if (data.name) {\n ctx.validateTextFileExtension(data.name);\n updateMetadata.name = data.name;\n updateMetadata.mimeType = getMimeTypeFromFilename(data.name);\n }\n\n const updatedFile = await ctx.getDrive().files.update({\n fileId: data.fileId,\n requestBody: updateMetadata,\n media: {\n mimeType: updateMetadata.mimeType || currentMimeType,\n body: data.content\n },\n fields: 'id, name, modifiedTime, webViewLink',\n supportsAllDrives: true\n });\n\n return {\n content: [{\n type: \"text\",\n text: `Updated file: ${updatedFile.data.name}\\nModified: ${updatedFile.data.modifiedTime}`\n }],\n isError: false\n };\n }\n\n case \"createFolder\": {\n const validation = CreateFolderSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const data = validation.data;\n\n const parentFolderId = await ctx.resolveFolderId(data.parent);\n\n // Check if folder already exists\n const existingFolderId = await ctx.checkFileExists(data.name, parentFolderId);\n if (existingFolderId) {\n return errorResponse(\n `A folder named \"${data.name}\" already exists in this location. ` +\n `Folder ID: ${existingFolderId}`\n );\n }\n const folderMetadata = {\n name: data.name,\n mimeType: FOLDER_MIME_TYPE,\n parents: [parentFolderId]\n };\n\n const folder = await ctx.getDrive().files.create({\n requestBody: folderMetadata,\n fields: 'id, name, webViewLink',\n supportsAllDrives: true\n });\n\n ctx.log('Folder created successfully', { folderId: folder.data.id, name: folder.data.name });\n\n return {\n content: [{\n type: \"text\",\n text: `Created folder: ${folder.data.name}\\nID: ${folder.data.id}`\n }],\n isError: false\n };\n }\n\n case \"listFolder\": {\n const validation = ListFolderSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const data = validation.data;\n\n // Default to root if no folder specified\n const targetFolderId = data.folderId || 'root';\n\n const res = await ctx.getDrive().files.list({\n q: `'${targetFolderId}' in parents and trashed = false`,\n pageSize: Math.min(data.pageSize || 50, 100),\n pageToken: data.pageToken,\n fields: \"nextPageToken, files(id, name, mimeType, modifiedTime, size)\",\n orderBy: \"name\",\n includeItemsFromAllDrives: true,\n supportsAllDrives: true\n });\n\n const files = res.data.files || [];\n const formattedFiles = files.map((file: drive_v3.Schema$File) => {\n const isFolder = file.mimeType === FOLDER_MIME_TYPE;\n return `${isFolder ? '\uD83D\uDCC1' : '\uD83D\uDCC4'} ${file.name} (ID: ${file.id})`;\n }).join('\\n');\n\n let response = `Contents of folder:\\n\\n${formattedFiles}`;\n if (res.data.nextPageToken) {\n response += `\\n\\nMore items available. Use pageToken: ${res.data.nextPageToken}`;\n }\n\n return {\n content: [{ type: \"text\", text: response }],\n isError: false\n };\n }\n\n case \"listSharedDrives\": {\n const validation = ListSharedDrivesSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const data = validation.data;\n\n const res = await ctx.getDrive().drives.list({\n pageSize: Math.min(data.pageSize || 50, 100),\n pageToken: data.pageToken,\n fields: 'nextPageToken, drives(id, name, createdTime, hidden)'\n });\n\n const drives = res.data.drives || [];\n if (drives.length === 0) {\n return { content: [{ type: 'text', text: 'No shared drives found.' }], isError: false };\n }\n\n const formatted = drives\n .map((d: drive_v3.Schema$Drive) => `${d.name} (ID: ${d.id}${d.hidden ? ', hidden' : ''})`)\n .join('\\n');\n\n let response = `Found ${drives.length} shared drives:\\n${formatted}`;\n if (res.data.nextPageToken) {\n response += `\\n\\nMore results available. Use pageToken: ${res.data.nextPageToken}`;\n }\n\n return {\n content: [{ type: 'text', text: response }],\n isError: false,\n };\n }\n\n case \"deleteItem\": {\n const validation = DeleteItemSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const data = validation.data;\n\n const item = await ctx.getDrive().files.get({ fileId: data.itemId, fields: 'name', supportsAllDrives: true });\n\n // Move to trash instead of permanent deletion\n await ctx.getDrive().files.update({\n fileId: data.itemId,\n requestBody: {\n trashed: true\n },\n supportsAllDrives: true\n });\n\n ctx.log('Item moved to trash successfully', { itemId: data.itemId, name: item.data.name });\n return {\n content: [{ type: \"text\", text: `Successfully moved to trash: ${item.data.name}` }],\n isError: false\n };\n }\n\n case \"renameItem\": {\n const validation = RenameItemSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const data = validation.data;\n\n // If it's a text file, check extension\n const item = await ctx.getDrive().files.get({ fileId: data.itemId, fields: 'name, mimeType', supportsAllDrives: true });\n if (Object.values(TEXT_MIME_TYPES).includes(item.data.mimeType || '')) {\n ctx.validateTextFileExtension(data.newName);\n }\n\n const updatedItem = await ctx.getDrive().files.update({\n fileId: data.itemId,\n requestBody: { name: data.newName },\n fields: 'id, name, modifiedTime',\n supportsAllDrives: true\n });\n\n return {\n content: [{\n type: \"text\",\n text: `Successfully renamed \"${item.data.name}\" to \"${updatedItem.data.name}\"`\n }],\n isError: false\n };\n }\n\n case \"moveItem\": {\n const validation = MoveItemSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const data = validation.data;\n\n const destinationFolderId = data.destinationFolderId ?\n await ctx.resolveFolderId(data.destinationFolderId) :\n 'root';\n\n // Check we aren't moving a folder into itself or its descendant\n if (data.destinationFolderId === data.itemId) {\n return errorResponse(\"Cannot move a folder into itself.\");\n }\n\n const item = await ctx.getDrive().files.get({ fileId: data.itemId, fields: 'name, parents', supportsAllDrives: true });\n\n // Perform move\n await ctx.getDrive().files.update({\n fileId: data.itemId,\n addParents: destinationFolderId,\n removeParents: item.data.parents?.join(',') || '',\n fields: 'id, name, parents',\n supportsAllDrives: true\n });\n\n // Get the destination folder name for a nice response\n const destinationFolder = await ctx.getDrive().files.get({\n fileId: destinationFolderId,\n fields: 'name',\n supportsAllDrives: true\n });\n\n return {\n content: [{\n type: \"text\",\n text: `Successfully moved \"${item.data.name}\" to \"${destinationFolder.data.name}\"`\n }],\n isError: false\n };\n }\n\n case \"copyFile\": {\n const validation = CopyFileSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const data = validation.data;\n\n // Get original file info\n const originalFile = await ctx.getDrive().files.get({\n fileId: data.fileId,\n fields: 'name,parents',\n supportsAllDrives: true\n });\n\n const copyMetadata: any = {\n name: data.newName || `Copy of ${originalFile.data.name}`\n };\n\n if (data.parentFolderId) {\n const resolvedParentId = await ctx.resolveFolderId(data.parentFolderId);\n copyMetadata.parents = [resolvedParentId];\n } else if (originalFile.data.parents) {\n copyMetadata.parents = originalFile.data.parents;\n }\n\n const response = await ctx.getDrive().files.copy({\n fileId: data.fileId,\n requestBody: copyMetadata,\n fields: 'id,name,webViewLink,parents',\n supportsAllDrives: true\n });\n\n return {\n content: [{ type: \"text\", text: `Successfully copied file as \"${response.data.name}\"\\nNew file ID: ${response.data.id}\\nLink: ${response.data.webViewLink}` }],\n isError: false\n };\n }\n\n case \"createShortcut\": {\n const validation = CreateShortcutSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const data = validation.data;\n\n const parentId = await ctx.resolveFolderId(data.parentFolderId);\n\n // Get target file metadata for default name\n const targetFile = await ctx.getDrive().files.get({\n fileId: data.targetFileId,\n fields: 'id, name, mimeType',\n supportsAllDrives: true\n });\n\n const shortcutName = data.shortcutName || targetFile.data.name || 'Shortcut';\n\n const shortcut = await ctx.getDrive().files.create({\n requestBody: {\n name: shortcutName,\n mimeType: SHORTCUT_MIME_TYPE,\n shortcutDetails: {\n targetId: data.targetFileId\n },\n parents: [parentId]\n },\n fields: 'id, name, webViewLink, shortcutDetails',\n supportsAllDrives: true\n });\n\n ctx.log('Shortcut created', {\n shortcutId: shortcut.data.id,\n targetId: data.targetFileId,\n name: shortcutName\n });\n\n return {\n content: [{\n type: \"text\",\n text: `Shortcut created successfully!\\n\\nShortcut: ${shortcut.data.name} (${shortcut.data.id})\\nTarget: ${targetFile.data.name} (${data.targetFileId})\\nLocation: folder ${parentId}\\nLink: ${shortcut.data.webViewLink || 'N/A'}`\n }],\n isError: false\n };\n }\n\n case \"lockFile\": {\n const validation = LockFileSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const data = validation.data;\n\n const fileInfo = await ctx.getDrive().files.get({\n fileId: data.fileId,\n fields: 'id, name, contentRestrictions',\n supportsAllDrives: true\n });\n\n const existingRestrictions = fileInfo.data.contentRestrictions || [];\n if (existingRestrictions.some((r) => r.readOnly)) {\n return {\n content: [{\n type: \"text\",\n text: `File \"${fileInfo.data.name}\" is already locked.`\n }],\n isError: false\n };\n }\n\n await ctx.getDrive().files.update({\n fileId: data.fileId,\n requestBody: {\n contentRestrictions: [{\n readOnly: true,\n reason: data.reason || 'Locked via MCP',\n ownerRestricted: data.ownerRestricted ?? false\n }]\n },\n supportsAllDrives: true\n });\n\n ctx.log('File locked', { fileId: data.fileId, name: fileInfo.data.name, reason: data.reason });\n\n return {\n content: [{\n type: \"text\",\n text: `File locked successfully!\\n\\nFile: ${fileInfo.data.name}\\nReason: ${data.reason || 'Locked via MCP'}${data.ownerRestricted ? '\\nOwner-restricted: only the file owner can unlock' : ''}\\n\\nThe file is now read-only and cannot be edited or deleted.`\n }],\n isError: false\n };\n }\n\n case \"unlockFile\": {\n const validation = UnlockFileSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const data = validation.data;\n\n const fileInfo = await ctx.getDrive().files.get({\n fileId: data.fileId,\n fields: 'id, name, contentRestrictions',\n supportsAllDrives: true\n });\n\n const existingRestrictions = fileInfo.data.contentRestrictions || [];\n if (!existingRestrictions.some((r) => r.readOnly)) {\n return {\n content: [{\n type: \"text\",\n text: `File \"${fileInfo.data.name}\" is not locked.`\n }],\n isError: false\n };\n }\n\n await ctx.getDrive().files.update({\n fileId: data.fileId,\n requestBody: {\n contentRestrictions: [{ readOnly: false }]\n },\n supportsAllDrives: true\n });\n\n ctx.log('File unlocked', { fileId: data.fileId, name: fileInfo.data.name });\n\n return {\n content: [{\n type: \"text\",\n text: `File unlocked successfully!\\n\\nFile: ${fileInfo.data.name}\\n\\nThe file can now be edited and deleted.`\n }],\n isError: false\n };\n }\n\n case \"uploadFile\": {\n const validation = UploadFileSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const data = validation.data;\n\n // Validate local file exists\n if (!existsSync(data.localPath)) {\n return errorResponse(`File not found: ${data.localPath}`);\n }\n\n const stats = statSync(data.localPath);\n const fileName = data.name || data.localPath.split(/[\\\\/]/).pop() || 'upload';\n const ext = fileName.split('.').pop()?.toLowerCase() || '';\n const detectedMime = data.mimeType || BINARY_MIME_TYPES[ext] || 'application/octet-stream';\n const parentId = await ctx.resolveFolderId(data.parentFolderId);\n\n // Google Workspace conversion mapping\n const GOOGLE_FORMAT_MAP: Record<string, string> = {\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': 'application/vnd.google-apps.document',\n 'application/msword': 'application/vnd.google-apps.document',\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'application/vnd.google-apps.spreadsheet',\n 'application/vnd.ms-excel': 'application/vnd.google-apps.spreadsheet',\n 'application/vnd.openxmlformats-officedocument.presentationml.presentation': 'application/vnd.google-apps.presentation',\n 'application/vnd.ms-powerpoint': 'application/vnd.google-apps.presentation',\n };\n\n const targetMimeType = data.convertToGoogleFormat ? GOOGLE_FORMAT_MAP[detectedMime] : undefined;\n\n if (data.convertToGoogleFormat && !targetMimeType) {\n return errorResponse(\n `Cannot convert MIME type \"${detectedMime}\" to a Google Workspace format. ` +\n `Supported: .docx, .doc, .xlsx, .xls, .pptx, .ppt`\n );\n }\n\n const uploadName = targetMimeType ? fileName.replace(/\\.[^.]+$/, '') : fileName;\n\n ctx.log('Uploading file', { localPath: data.localPath, name: uploadName, mimeType: detectedMime, convertToGoogle: !!targetMimeType, size: stats.size });\n\n const requestBody: any = {\n name: uploadName,\n parents: [parentId]\n };\n if (targetMimeType) {\n requestBody.mimeType = targetMimeType;\n }\n\n const file = await ctx.getDrive().files.create({\n requestBody,\n media: {\n mimeType: detectedMime,\n body: createReadStream(data.localPath)\n },\n fields: 'id, name, size, mimeType, webViewLink',\n supportsAllDrives: true\n });\n\n ctx.log('File uploaded successfully', { fileId: file.data?.id });\n return {\n content: [{\n type: \"text\",\n text: [\n `Uploaded: ${file.data?.name || fileName}`,\n `ID: ${file.data?.id || 'unknown'}`,\n `Size: ${file.data?.size || stats.size} bytes`,\n `Type: ${file.data?.mimeType || detectedMime}`,\n file.data?.webViewLink ? `Link: ${file.data.webViewLink}` : ''\n ].filter(Boolean).join('\\n')\n }],\n isError: false\n };\n }\n\n case \"downloadFile\": {\n const validation = DownloadFileSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const data = validation.data;\n const downloadResult = await downloadDriveFile(ctx.getDrive(), data, ctx.log);\n\n return {\n content: [{\n type: 'text',\n text: [\n `Downloaded: ${downloadResult.driveName}`,\n `Saved to: ${downloadResult.resolvedPath}`,\n `Size: ${downloadResult.size} bytes`,\n downloadResult.isWorkspaceFile\n ? `Export format: ${downloadResult.exportMime}`\n : `Type: ${downloadResult.driveMimeType}`,\n ].join('\\n'),\n }],\n isError: false,\n };\n }\n\n case \"listPermissions\": {\n const validation = ListPermissionsSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const data = validation.data;\n\n const response = await ctx.getDrive().permissions.list({\n fileId: data.fileId,\n fields: 'permissions(id,type,role,emailAddress,domain,displayName,permissionDetails(inherited,inheritedFrom,permissionType))',\n supportsAllDrives: true,\n });\n\n const permissions = response.data.permissions || [];\n if (permissions.length === 0) {\n return { content: [{ type: 'text', text: 'No permissions found.' }], isError: false };\n }\n\n const lines = permissions.map((p) => {\n const who = p.emailAddress || p.domain || p.displayName || p.type || 'unknown';\n const inherited = p.permissionDetails?.some((d) => d.inherited === true) ?? false;\n const inheritedFrom = p.permissionDetails?.find((d) => d.inheritedFrom)?.inheritedFrom;\n const inheritedMarker = inherited\n ? ` [inherited${inheritedFrom ? ` from ${inheritedFrom}` : ''}]`\n : ' [direct]';\n return `- ${p.id}: ${who} (${p.type}) => ${p.role}${inheritedMarker}`;\n });\n\n return { content: [{ type: 'text', text: `Permissions for file ${data.fileId}:\\n${lines.join('\\n')}` }], isError: false };\n }\n\n case \"addPermission\": {\n const validation = AddPermissionSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const data = validation.data;\n\n const response = await ctx.getDrive().permissions.create({\n fileId: data.fileId,\n requestBody: {\n type: data.type,\n role: data.role,\n emailAddress: data.emailAddress,\n },\n sendNotificationEmail: data.sendNotificationEmail,\n fields: 'id,type,role,emailAddress',\n supportsAllDrives: true,\n });\n\n return { content: [{ type: 'text', text: `Permission added: ${response.data.id} (${response.data.role}) for ${response.data.emailAddress || data.emailAddress}` }], isError: false };\n }\n\n case \"updatePermission\": {\n const validation = UpdatePermissionSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const data = validation.data;\n\n const response = await ctx.getDrive().permissions.update({\n fileId: data.fileId,\n permissionId: data.permissionId,\n requestBody: { role: data.role },\n fields: 'id,type,role,emailAddress',\n supportsAllDrives: true,\n });\n\n return { content: [{ type: 'text', text: `Permission updated: ${response.data.id} => ${response.data.role}` }], isError: false };\n }\n\n case \"removePermission\": {\n const validation = RemovePermissionSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const data = validation.data;\n\n let permissionId: string | undefined = data.permissionId;\n if (!permissionId && data.emailAddress) {\n const listed = await ctx.getDrive().permissions.list({\n fileId: data.fileId,\n fields: 'permissions(id,type,emailAddress)',\n supportsAllDrives: true,\n });\n const found = (listed.data.permissions || []).find(\n (p) => p.type === 'user' && (p.emailAddress || '').toLowerCase() === data.emailAddress!.toLowerCase(),\n );\n if (!found?.id) {\n return errorResponse(`No permission found for ${data.emailAddress}`);\n }\n permissionId = found.id;\n }\n\n if (!permissionId) {\n return errorResponse(\"Could not resolve a permission ID to remove\");\n }\n\n await ctx.getDrive().permissions.delete({\n fileId: data.fileId,\n permissionId,\n supportsAllDrives: true,\n });\n\n return { content: [{ type: 'text', text: `Permission removed: ${permissionId}` }], isError: false };\n }\n\n case \"shareFile\": {\n const validation = ShareFileSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const data = validation.data;\n\n // Idempotent behavior: update existing permission for the same principal instead of creating duplicates.\n const existing = await ctx.getDrive().permissions.list({\n fileId: data.fileId,\n fields: 'permissions(id,type,emailAddress,role)',\n supportsAllDrives: true,\n });\n\n const existingPerm = (existing.data.permissions || []).find(\n (p) => p.type === 'user' && (p.emailAddress || '').toLowerCase() === data.emailAddress.toLowerCase(),\n );\n\n if (existingPerm?.id) {\n if (existingPerm.role === data.role) {\n return {\n content: [{ type: 'text', text: `No changes needed: ${data.emailAddress} already has role ${data.role}. Permission ID: ${existingPerm.id}` }],\n isError: false,\n };\n }\n\n const updated = await ctx.getDrive().permissions.update({\n fileId: data.fileId,\n permissionId: existingPerm.id,\n requestBody: { role: data.role },\n fields: 'id,type,role,emailAddress',\n supportsAllDrives: true,\n });\n\n return {\n content: [{ type: 'text', text: `Updated existing permission for ${updated.data.emailAddress || data.emailAddress} to ${updated.data.role}. Permission ID: ${updated.data.id}` }],\n isError: false,\n };\n }\n\n const response = await ctx.getDrive().permissions.create({\n fileId: data.fileId,\n requestBody: {\n type: 'user',\n role: data.role,\n emailAddress: data.emailAddress,\n },\n sendNotificationEmail: data.sendNotificationEmail,\n fields: 'id,type,role,emailAddress',\n supportsAllDrives: true,\n });\n\n return {\n content: [{ type: 'text', text: `Shared file with ${response.data.emailAddress || data.emailAddress} as ${response.data.role}. Permission ID: ${response.data.id}` }],\n isError: false,\n };\n }\n\n case \"convertPdfToGoogleDoc\": {\n const validation = ConvertPdfToGoogleDocSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const data = validation.data;\n\n const source = await ctx.getDrive().files.get({\n fileId: data.fileId,\n fields: 'id,name,mimeType,parents',\n supportsAllDrives: true,\n });\n\n if (source.data.mimeType !== 'application/pdf') {\n return errorResponse(`File ${data.fileId} is not a PDF (mimeType=${source.data.mimeType || 'unknown'})`);\n }\n\n const parentId = data.parentFolderId || source.data.parents?.[0];\n const converted = await ctx.getDrive().files.copy({\n fileId: data.fileId,\n requestBody: {\n name: data.newName || `${source.data.name || 'Converted PDF'} (Doc)`,\n mimeType: 'application/vnd.google-apps.document',\n ...(parentId ? { parents: [parentId] } : {}),\n },\n fields: 'id,name,webViewLink,mimeType',\n supportsAllDrives: true,\n });\n\n return { content: [{ type: 'text', text: `Converted PDF to Google Doc: ${converted.data.name}\\nID: ${converted.data.id}\\nLink: ${converted.data.webViewLink}` }], isError: false };\n }\n\n case \"bulkConvertFolderPdfs\": {\n const validation = BulkConvertFolderPdfsSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const data = validation.data;\n\n const list = await ctx.getDrive().files.list({\n q: `'${data.folderId}' in parents and mimeType='application/pdf' and trashed=false`,\n pageSize: data.maxResults,\n fields: 'files(id,name,mimeType)',\n includeItemsFromAllDrives: true,\n supportsAllDrives: true,\n });\n\n const files = list.data.files || [];\n const results: Array<{ id?: string; name?: string; docId?: string; ok: boolean; error?: string }> = [];\n\n // Sequential processing is intentional \u2014 parallel copies trigger Google API rate limits.\n for (const f of files) {\n try {\n const converted = await ctx.getDrive().files.copy({\n fileId: f.id!,\n requestBody: {\n name: `${f.name || 'Converted PDF'} (Doc)`,\n mimeType: 'application/vnd.google-apps.document',\n parents: [data.folderId],\n },\n fields: 'id,name',\n supportsAllDrives: true,\n });\n results.push({ id: f.id ?? undefined, name: f.name ?? undefined, docId: converted.data.id ?? undefined, ok: true });\n } catch (err: any) {\n const message = err?.message || 'Unknown conversion error';\n results.push({ id: f.id ?? undefined, name: f.name ?? undefined, ok: false, error: message });\n if (!data.continueOnError) break;\n }\n }\n\n const ok = results.filter(r => r.ok).length;\n const fail = results.length - ok;\n return {\n content: [{ type: 'text', text: `Bulk PDF conversion finished. Processed=${results.length}, Success=${ok}, Failed=${fail}\\n\\n${results.map(r => r.ok ? `\u2705 ${r.name} -> ${r.docId}` : `\u274C ${r.name}: ${r.error}`).join('\\n')}` }],\n isError: false,\n };\n }\n\n case \"uploadPdfWithSplit\": {\n const validation = UploadPdfWithSplitSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const data = validation.data;\n\n if (!existsSync(data.localPath)) return errorResponse(`File not found: ${data.localPath}`);\n const parentId = await ctx.resolveFolderId(data.parentFolderId);\n\n if (!data.split) {\n const fileName = data.namePrefix || basename(data.localPath) || 'upload.pdf';\n const uploaded = await ctx.getDrive().files.create({\n requestBody: { name: fileName, parents: [parentId] },\n media: { mimeType: 'application/pdf', body: createReadStream(data.localPath) },\n fields: 'id,name,webViewLink',\n supportsAllDrives: true,\n });\n\n return {\n content: [{ type: 'text', text: `Uploaded PDF without split: ${uploaded.data.name}\\nID: ${uploaded.data.id}` }],\n isError: false,\n };\n }\n\n const maxPagesPerChunk = data.maxPagesPerChunk ?? 25;\n const baseName = data.namePrefix || basename(data.localPath, extname(data.localPath));\n\n let tempDir: string | undefined;\n try {\n const splitResult = await splitPdfIntoChunkFiles(data.localPath, maxPagesPerChunk);\n tempDir = splitResult.tempDir;\n\n const uploadedParts: Array<{ id?: string | null; name?: string | null }> = [];\n for (let i = 0; i < splitResult.files.length; i++) {\n const partPath = splitResult.files[i];\n const partName = `${baseName}-part-${i + 1}.pdf`;\n\n const uploaded = await ctx.getDrive().files.create({\n requestBody: { name: partName, parents: [parentId] },\n media: { mimeType: 'application/pdf', body: createReadStream(partPath) },\n fields: 'id,name,webViewLink',\n supportsAllDrives: true,\n });\n\n uploadedParts.push({ id: uploaded.data.id, name: uploaded.data.name });\n }\n\n const lines = uploadedParts.map((p, idx) => `- part ${idx + 1}: ${p.name} (ID: ${p.id})`);\n return {\n content: [{\n type: 'text',\n text: `Uploaded split PDF into ${uploadedParts.length} part(s) using maxPagesPerChunk=${maxPagesPerChunk}\\n${lines.join('\\n')}`,\n }],\n isError: false,\n };\n } finally {\n if (tempDir) {\n await rm(tempDir, { recursive: true, force: true });\n }\n }\n }\n\n case \"getRevisions\": {\n const validation = GetRevisionsSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const data = validation.data;\n\n const response = await ctx.getDrive().revisions.list({\n fileId: data.fileId,\n pageSize: data.pageSize,\n pageToken: data.pageToken,\n fields: 'nextPageToken,revisions(id,modifiedTime,lastModifyingUser(displayName,emailAddress),keepForever,size,originalFilename)',\n });\n\n const revisions: drive_v3.Schema$Revision[] = response.data.revisions || [];\n if (revisions.length === 0) {\n return { content: [{ type: 'text', text: `No revisions found for file ${data.fileId}.` }], isError: false };\n }\n\n const lines = revisions.map((r: drive_v3.Schema$Revision) => {\n const who = r.lastModifyingUser?.displayName || r.lastModifyingUser?.emailAddress || 'unknown';\n return `- ${r.id}: ${r.modifiedTime || 'unknown-time'} by ${who}${r.keepForever ? ' [kept]' : ''}`;\n });\n\n let text = `Revisions for file ${data.fileId}:\\n${lines.join('\\n')}`;\n if (response.data.nextPageToken) {\n text += `\\n\\nMore revisions available. Use pageToken=\"${response.data.nextPageToken}\" to fetch the next page.`;\n }\n\n return {\n content: [{ type: 'text', text }],\n isError: false,\n };\n }\n\n case \"restoreRevision\": {\n const validation = RestoreRevisionSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const data = validation.data;\n\n if (!data.confirm) {\n return errorResponse('Refusing restore: set confirm=true to restore a revision.');\n }\n\n try {\n // Get current file metadata to determine restore strategy\n const current = await ctx.getDrive().files.get({\n fileId: data.fileId,\n fields: 'name,mimeType',\n supportsAllDrives: true,\n });\n\n const fileMimeType = current.data.mimeType || '';\n const isWorkspaceFile = fileMimeType.startsWith('application/vnd.google-apps.');\n\n let revisionBody: unknown;\n let uploadMimeType: string;\n\n if (isWorkspaceFile) {\n // Workspace files don't support revisions.get with alt=media.\n // Use the revision's exportLinks to fetch content in an editable format.\n const revision = await ctx.getDrive().revisions.get({\n fileId: data.fileId,\n revisionId: data.revisionId,\n fields: 'id,exportLinks',\n });\n\n const exportLinks = (revision.data.exportLinks as Record<string, string> | null) || {};\n\n // Build preference list: editable formats from GOOGLE_WORKSPACE_EXPORT_FORMATS, excluding pdf\n const formatMap = GOOGLE_WORKSPACE_EXPORT_FORMATS[fileMimeType];\n const editableMimes = formatMap\n ? Object.entries(formatMap).filter(([ext]) => ext !== 'pdf').map(([, mime]) => mime)\n : [];\n\n // Pick the first editable MIME type available in exportLinks\n const selectedMime = editableMimes.find((m) => exportLinks[m])\n || Object.keys(exportLinks).find((m) => m !== 'application/pdf')\n || Object.keys(exportLinks)[0];\n\n if (!selectedMime || !exportLinks[selectedMime]) {\n return errorResponse('Selected revision has no usable export links for restore.');\n }\n\n uploadMimeType = selectedMime;\n\n // Fetch revision content from the export link using authenticated request\n const exportResponse = await ctx.authClient.request({ url: exportLinks[selectedMime], responseType: 'stream' });\n revisionBody = exportResponse.data;\n } else {\n // For binary files, download the revision content directly\n const revision = await ctx.getDrive().revisions.get(\n { fileId: data.fileId, revisionId: data.revisionId, alt: 'media' },\n { responseType: 'stream' },\n );\n revisionBody = revision.data;\n uploadMimeType = fileMimeType || 'application/octet-stream';\n }\n\n await ctx.getDrive().files.update({\n fileId: data.fileId,\n media: {\n mimeType: uploadMimeType,\n body: revisionBody,\n },\n supportsAllDrives: true,\n });\n\n const restoreMsg = `Restored file ${data.fileId} (${current.data.name || 'unnamed'}) from revision ${data.revisionId}.`;\n const workspaceWarning = isWorkspaceFile\n ? '\\n\\nWarning: This workspace file was restored via export/import. Some formatting or features (e.g. comments, suggestions, version history metadata) may have been lost.'\n : '';\n\n return {\n content: [{\n type: 'text',\n text: restoreMsg + workspaceWarning,\n }],\n isError: false,\n };\n } catch (err: unknown) {\n return errorResponse(`Failed to restore revision: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n case \"authGetStatus\": {\n const tokenPath = getSecureTokenPath();\n const tokenFileExists = existsSync(tokenPath);\n let scopeStatus: ReturnType<typeof resolveScopeStatus>;\n try {\n scopeStatus = resolveScopeStatus(ctx);\n } catch (e: unknown) {\n return errorResponse(`Invalid scope configuration: ${e instanceof Error ? e.message : String(e)}`);\n }\n const { requestedScopes, grantedScopes, missingScopes } = scopeStatus;\n const expiryDate = ctx.authClient?.credentials?.expiry_date as number | undefined;\n const expiresInSec = expiryDate ? Math.floor((expiryDate - Date.now()) / 1000) : null;\n\n const payload = {\n tokenFilePath: tokenPath,\n tokenFileExists,\n hasAccessToken: !!ctx.authClient?.credentials?.access_token,\n hasRefreshToken: !!ctx.authClient?.credentials?.refresh_token,\n expiryDate: expiryDate || null,\n expiresInSec,\n requestedScopes,\n grantedScopes,\n missingScopes,\n };\n\n const status =\n !tokenFileExists || !payload.hasRefreshToken ? 'needs_reauth' :\n missingScopes.length > 0 ? 'scope_mismatch' :\n 'ok';\n\n let text = `Auth status (${status}):\\n${JSON.stringify(payload, null, 2)}\\n\\nSummary: token file ${tokenFileExists ? 'found' : 'missing'}, missing scopes=${missingScopes.length}.`;\n if (grantedScopes.length === 0 && payload.hasAccessToken) {\n text += '\\nNote: granted scopes may appear empty when the token was loaded from disk. This does not necessarily indicate missing permissions.';\n }\n\n return {\n content: [{ type: 'text', text }],\n isError: false,\n };\n }\n\n case \"authListScopes\": {\n let scopeStatus: ReturnType<typeof resolveScopeStatus>;\n try {\n scopeStatus = resolveScopeStatus(ctx);\n } catch (e: unknown) {\n return errorResponse(`Invalid scope configuration: ${e instanceof Error ? e.message : String(e)}`);\n }\n const { requestedScopes, grantedScopes, missingScopes } = scopeStatus;\n const presetsResolved = Object.fromEntries(\n Object.entries(SCOPE_PRESETS).map(([k, v]) => [k, v.map((s) => SCOPE_ALIASES[s] || s)]),\n );\n\n let text = `Scopes:\\n${JSON.stringify({ requestedScopes, grantedScopes, missingScopes, presets: presetsResolved }, null, 2)}`;\n if (grantedScopes.length === 0 && !!ctx.authClient?.credentials?.access_token) {\n text += '\\nNote: granted scopes may appear empty when the token was loaded from disk. This does not necessarily indicate missing permissions.';\n }\n\n return {\n content: [{ type: 'text', text }],\n isError: false,\n };\n }\n\n case \"authTestFileAccess\": {\n const validation = AuthTestFileAccessSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const data = validation.data;\n\n try {\n let check: { mode: string; [key: string]: unknown };\n if (data.fileId) {\n const file = await ctx.getDrive().files.get({\n fileId: data.fileId,\n fields: 'id,name,mimeType,permissions',\n supportsAllDrives: true,\n });\n check = { mode: 'file', fileId: file.data.id, name: file.data.name, mimeType: file.data.mimeType };\n } else {\n const list = await ctx.getDrive().files.list({\n pageSize: 1,\n fields: 'files(id,name,mimeType)',\n includeItemsFromAllDrives: true,\n supportsAllDrives: true,\n });\n check = { mode: 'list', visibleCount: list.data.files?.length || 0, sample: list.data.files?.[0] || null };\n }\n\n return {\n content: [{ type: 'text', text: `Auth access check OK:\\n${JSON.stringify(check, null, 2)}` }],\n isError: false,\n };\n } catch (e: unknown) {\n const message = e instanceof Error ? e.message : String(e);\n return {\n content: [{ type: 'text', text: `Auth access check failed:\\n${JSON.stringify({ message }, null, 2)}` }],\n isError: true,\n };\n }\n }\n\n default:\n return null;\n }\n}\n", "import { createWriteStream, existsSync, renameSync, statSync, unlinkSync } from 'fs';\nimport { basename, dirname, extname, isAbsolute, join, relative, resolve } from 'path';\nimport { pipeline } from 'stream/promises';\n\nexport const GOOGLE_WORKSPACE_EXPORT_FORMATS: Record<string, Record<string, string>> = {\n 'application/vnd.google-apps.document': {\n pdf: 'application/pdf',\n docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n md: 'text/markdown',\n txt: 'text/plain',\n html: 'text/html',\n rtf: 'application/rtf',\n odt: 'application/vnd.oasis.opendocument.text',\n epub: 'application/epub+zip',\n },\n 'application/vnd.google-apps.spreadsheet': {\n xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n csv: 'text/csv',\n pdf: 'application/pdf',\n ods: 'application/vnd.oasis.opendocument.spreadsheet',\n tsv: 'text/tab-separated-values',\n html: 'text/html',\n },\n 'application/vnd.google-apps.presentation': {\n pptx: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',\n pdf: 'application/pdf',\n txt: 'text/plain',\n odp: 'application/vnd.oasis.opendocument.presentation',\n },\n 'application/vnd.google-apps.drawing': {\n png: 'image/png',\n svg: 'image/svg+xml',\n pdf: 'application/pdf',\n jpg: 'image/jpeg',\n },\n};\n\nexport const GOOGLE_WORKSPACE_DEFAULT_EXPORT: Record<string, { mimeType: string; ext: string }> = {\n 'application/vnd.google-apps.document': { mimeType: 'application/pdf', ext: '.pdf' },\n 'application/vnd.google-apps.spreadsheet': { mimeType: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', ext: '.xlsx' },\n 'application/vnd.google-apps.presentation': { mimeType: 'application/vnd.openxmlformats-officedocument.presentationml.presentation', ext: '.pptx' },\n 'application/vnd.google-apps.drawing': { mimeType: 'image/png', ext: '.png' },\n};\n\nexport type DownloadFileArgs = {\n fileId: string;\n localPath: string;\n exportMimeType?: string;\n overwrite?: boolean;\n};\n\nexport type DownloadFileResult = {\n driveName: string;\n driveMimeType: string;\n exportMime?: string;\n isWorkspaceFile: boolean;\n resolvedPath: string;\n size: number;\n};\n\ntype DriveGetParams = {\n fileId: string;\n fields?: string;\n supportsAllDrives?: boolean;\n alt?: 'media';\n};\n\ntype DriveExportParams = {\n fileId: string;\n mimeType?: string;\n};\n\ntype DriveRequestOptions = {\n responseType?: 'stream';\n};\n\ntype DriveResponse = {\n data: any;\n};\n\ntype DriveLike = {\n files: {\n get: (params: DriveGetParams, options?: DriveRequestOptions) => Promise<DriveResponse>;\n export: (params: DriveExportParams, options?: DriveRequestOptions) => Promise<DriveResponse>;\n };\n};\n\nfunction sanitizeDriveFilename(driveName: string): string {\n return basename(driveName).replace(/^\\.+/, '') || 'download';\n}\n\nfunction isPathWithinDirectory(targetPath: string, directoryPath: string): boolean {\n const relativePath = relative(resolve(directoryPath), resolve(targetPath));\n return relativePath === '' || (!relativePath.startsWith('..') && !isAbsolute(relativePath));\n}\n\nfunction resolveWorkspaceExport(\n driveMimeType: string,\n args: DownloadFileArgs,\n resolvedPath: string,\n isDirectory: boolean,\n): { exportMime: string; fileExtForName: string } {\n const formatMap = GOOGLE_WORKSPACE_EXPORT_FORMATS[driveMimeType];\n if (!formatMap) {\n throw new Error(\n `Unsupported Google Workspace type for export: ${driveMimeType}. ` +\n 'Supported types: Document, Spreadsheet, Presentation, Drawing.'\n );\n }\n\n if (args.exportMimeType) {\n const validMimes = Object.values(formatMap);\n if (!validMimes.includes(args.exportMimeType)) {\n throw new Error(\n `Unsupported export format '${args.exportMimeType}' for ${driveMimeType}. ` +\n `Supported: ${Object.entries(formatMap).map(([ext, mime]) => `${mime} (.${ext})`).join(', ')}`\n );\n }\n\n const extForMime = Object.entries(formatMap).find(([, mime]) => mime === args.exportMimeType)?.[0] || 'bin';\n return { exportMime: args.exportMimeType, fileExtForName: `.${extForMime}` };\n }\n\n if (!isDirectory && extname(resolvedPath)) {\n const ext = extname(resolvedPath).slice(1).toLowerCase();\n if (formatMap[ext]) {\n return { exportMime: formatMap[ext], fileExtForName: `.${ext}` };\n }\n }\n\n const defaultExport = GOOGLE_WORKSPACE_DEFAULT_EXPORT[driveMimeType];\n return { exportMime: defaultExport.mimeType, fileExtForName: defaultExport.ext };\n}\n\nfunction buildTempPath(resolvedPath: string): string {\n const random = Math.random().toString(16).slice(2);\n return `${resolvedPath}.download-${Date.now()}-${random}.tmp`;\n}\n\nexport async function downloadDriveFile(\n drive: DriveLike,\n args: DownloadFileArgs,\n log: (message: string, data?: unknown) => void,\n): Promise<DownloadFileResult> {\n if (!isAbsolute(args.localPath)) {\n throw new Error('localPath must be an absolute path');\n }\n\n const normalizedLocalPath = resolve(args.localPath);\n\n const fileMeta = await drive.files.get({\n fileId: args.fileId,\n fields: 'id, name, mimeType, size',\n supportsAllDrives: true,\n });\n\n const driveMimeType = fileMeta.data.mimeType;\n const driveName = fileMeta.data.name || 'download';\n\n if (!driveMimeType) {\n throw new Error('File has no MIME type');\n }\n\n const isWorkspaceFile = driveMimeType.startsWith('application/vnd.google-apps');\n const overwrite = args.overwrite ?? false;\n\n let resolvedPath = normalizedLocalPath;\n let isDirectory = false;\n\n if (existsSync(resolvedPath)) {\n isDirectory = statSync(resolvedPath).isDirectory();\n } else {\n const parentDir = dirname(resolvedPath);\n if (!existsSync(parentDir)) {\n throw new Error(`Parent directory does not exist: ${parentDir}`);\n }\n }\n\n let exportMime: string | undefined;\n let fileExtForName = '';\n\n if (isWorkspaceFile) {\n const exportSelection = resolveWorkspaceExport(driveMimeType, args, resolvedPath, isDirectory);\n exportMime = exportSelection.exportMime;\n fileExtForName = exportSelection.fileExtForName;\n }\n\n if (isDirectory) {\n const safeName = sanitizeDriveFilename(driveName);\n let fileName = safeName;\n if (isWorkspaceFile) {\n const nameWithoutExt = safeName.replace(/\\.[^.]+$/, '');\n fileName = `${nameWithoutExt}${fileExtForName}`;\n }\n\n resolvedPath = join(resolvedPath, fileName);\n if (!isPathWithinDirectory(resolvedPath, normalizedLocalPath)) {\n throw new Error('Resolved file path escapes the target directory');\n }\n }\n\n const targetExists = existsSync(resolvedPath);\n if (targetExists && !overwrite) {\n throw new Error(`File already exists at ${resolvedPath}. Set overwrite: true to replace it.`);\n }\n\n log('Downloading file', {\n fileId: args.fileId,\n driveName,\n driveMimeType,\n isWorkspaceFile,\n exportMime,\n localPath: resolvedPath,\n });\n\n const response = isWorkspaceFile\n ? await drive.files.export({ fileId: args.fileId, mimeType: exportMime }, { responseType: 'stream' })\n : await drive.files.get({ fileId: args.fileId, alt: 'media', supportsAllDrives: true }, { responseType: 'stream' });\n\n const writePath = overwrite && targetExists ? buildTempPath(resolvedPath) : resolvedPath;\n const dest = createWriteStream(writePath);\n\n try {\n await pipeline(response.data, dest);\n if (writePath !== resolvedPath) {\n renameSync(writePath, resolvedPath);\n }\n } catch (downloadErr) {\n try {\n unlinkSync(writePath);\n } catch {\n // Ignore cleanup errors.\n }\n throw downloadErr;\n }\n\n const finalStats = statSync(resolvedPath);\n\n log('File downloaded successfully', {\n fileId: args.fileId,\n localPath: resolvedPath,\n size: finalStats.size,\n });\n\n return {\n driveName,\n driveMimeType,\n exportMime,\n isWorkspaceFile,\n resolvedPath,\n size: finalStats.size,\n };\n}\n", "import { z } from 'zod';\nimport JSZip from 'jszip';\nimport type { ToolDefinition, ToolContext, ToolResult } from '../types.js';\nimport { errorResponse } from '../types.js';\nimport { escapeDriveQuery } from '../utils.js';\nimport { uploadImageToDrive } from '../utils/driveImageUpload.js';\n\n// ---------------------------------------------------------------------------\n// Helper functions\n// ---------------------------------------------------------------------------\n\n// Pure helper \u2013 no context needed\nfunction hexToRgbColor(hex: string): { red: number; green: number; blue: number } | null {\n if (!hex) return null;\n let hexClean = hex.startsWith('#') ? hex.slice(1) : hex;\n\n if (hexClean.length === 3) {\n hexClean = hexClean[0] + hexClean[0] + hexClean[1] + hexClean[1] + hexClean[2] + hexClean[2];\n }\n if (hexClean.length !== 6) return null;\n const bigint = parseInt(hexClean, 16);\n if (isNaN(bigint)) return null;\n\n const r = ((bigint >> 16) & 255) / 255;\n const g = ((bigint >> 8) & 255) / 255;\n const b = (bigint & 255) / 255;\n\n return { red: r, green: g, blue: b };\n}\n\n// Inverse of hexToRgbColor \u2013 converts Google Docs API color object to hex string\nfunction rgbColorToHex(color: any): string | null {\n if (!color?.color?.rgbColor) return null;\n const rgb = color.color.rgbColor;\n const r = Math.round((rgb.red || 0) * 255);\n const g = Math.round((rgb.green || 0) * 255);\n const b = Math.round((rgb.blue || 0) * 255);\n return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;\n}\n\n// Helper to recursively collect all tabs with their nesting level\nfunction collectAllTabsWithLevel(tabs: any[], level: number = 0): Array<{ tab: any; level: number }> {\n const result: Array<{ tab: any; level: number }> = [];\n for (const tab of tabs) {\n result.push({ tab, level });\n if (tab.childTabs && tab.childTabs.length > 0) {\n result.push(...collectAllTabsWithLevel(tab.childTabs, level + 1));\n }\n }\n return result;\n}\n\n// Helper to recursively find a tab by ID in the tab tree\nfunction findTabById(tabs: any[], targetId: string): any | null {\n for (const tab of tabs) {\n if (tab.tabProperties?.tabId === targetId) {\n return tab;\n }\n if (tab.childTabs && tab.childTabs.length > 0) {\n const found = findTabById(tab.childTabs, targetId);\n if (found) return found;\n }\n }\n return null;\n}\n\n// Execute batch update for Google Docs\nasync function executeBatchUpdate(ctx: ToolContext, documentId: string, requests: any[]): Promise<any> {\n if (!requests || requests.length === 0) {\n return {};\n }\n\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n\n try {\n const response = await docs.documents.batchUpdate({\n documentId: documentId,\n requestBody: { requests },\n });\n return response.data;\n } catch (error: any) {\n ctx.log('Google Docs batchUpdate error:', error.message);\n if (error.code === 404) throw new Error(`Document not found (ID: ${documentId})`);\n if (error.code === 403) throw new Error(`Permission denied for document (ID: ${documentId})`);\n throw new Error(`Google Docs API Error: ${error.message}`);\n }\n}\n\n// Find text in a document and return the range indices\nasync function findTextRange(ctx: ToolContext, documentId: string, textToFind: string, instance: number = 1): Promise<{ startIndex: number; endIndex: number } | null> {\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n\n try {\n const res = await docs.documents.get({\n documentId,\n fields: 'body(content(paragraph(elements(startIndex,endIndex,textRun(content))),table,startIndex,endIndex))',\n });\n\n if (!res.data.body?.content) {\n return null;\n }\n\n // Collect all text segments with their positions\n let fullText = '';\n const segments: { text: string; start: number; end: number }[] = [];\n\n const collectTextFromContent = (content: any[]) => {\n content.forEach(element => {\n if (element.paragraph?.elements) {\n element.paragraph.elements.forEach((pe: any) => {\n if (pe.textRun?.content && pe.startIndex !== undefined && pe.endIndex !== undefined) {\n const text = pe.textRun.content;\n fullText += text;\n segments.push({ text, start: pe.startIndex, end: pe.endIndex });\n }\n });\n }\n\n // Handle tables recursively\n if (element.table?.tableRows) {\n element.table.tableRows.forEach((row: any) => {\n if (row.tableCells) {\n row.tableCells.forEach((cell: any) => {\n if (cell.content) {\n collectTextFromContent(cell.content);\n }\n });\n }\n });\n }\n });\n };\n\n collectTextFromContent(res.data.body.content);\n segments.sort((a, b) => a.start - b.start);\n\n // Find the specified instance\n let foundCount = 0;\n let searchStartIndex = 0;\n\n while (foundCount < instance) {\n const currentIndex = fullText.indexOf(textToFind, searchStartIndex);\n if (currentIndex === -1) break;\n\n foundCount++;\n\n if (foundCount === instance) {\n const targetStartInFullText = currentIndex;\n const targetEndInFullText = currentIndex + textToFind.length;\n let currentPosInFullText = 0;\n let startIndex = -1;\n let endIndex = -1;\n\n for (const seg of segments) {\n const segStartInFullText = currentPosInFullText;\n const segEndInFullText = segStartInFullText + seg.text.length;\n\n if (startIndex === -1 && targetStartInFullText >= segStartInFullText && targetStartInFullText < segEndInFullText) {\n startIndex = seg.start + (targetStartInFullText - segStartInFullText);\n }\n\n if (targetEndInFullText > segStartInFullText && targetEndInFullText <= segEndInFullText) {\n endIndex = seg.start + (targetEndInFullText - segStartInFullText);\n break;\n }\n\n currentPosInFullText = segEndInFullText;\n }\n\n if (startIndex !== -1 && endIndex !== -1) {\n return { startIndex, endIndex };\n }\n }\n\n searchStartIndex = currentIndex + 1;\n }\n\n return null;\n } catch (error: any) {\n ctx.log('Error finding text in document:', error.message);\n if (error.code === 404) throw new Error(`Document not found (ID: ${documentId})`);\n throw new Error(`Failed to search document: ${error.message}`);\n }\n}\n\n// Get paragraph range containing a specific index\nasync function getParagraphRange(ctx: ToolContext, documentId: string, indexWithin: number): Promise<{ startIndex: number; endIndex: number } | null> {\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n\n try {\n const res = await docs.documents.get({\n documentId,\n fields: 'body(content(startIndex,endIndex,paragraph,table))',\n });\n\n if (!res.data.body?.content) {\n return null;\n }\n\n const findParagraphInContent = (content: any[]): { startIndex: number; endIndex: number } | null => {\n for (const element of content) {\n if (element.startIndex !== undefined && element.endIndex !== undefined) {\n if (indexWithin >= element.startIndex && indexWithin < element.endIndex) {\n if (element.paragraph) {\n return { startIndex: element.startIndex, endIndex: element.endIndex };\n }\n\n // Check table cells recursively\n if (element.table?.tableRows) {\n for (const row of element.table.tableRows) {\n if (row.tableCells) {\n for (const cell of row.tableCells) {\n if (cell.content) {\n const result = findParagraphInContent(cell.content);\n if (result) return result;\n }\n }\n }\n }\n }\n }\n }\n }\n return null;\n };\n\n return findParagraphInContent(res.data.body.content);\n } catch (error: any) {\n ctx.log('Error getting paragraph range:', error.message);\n throw new Error(`Failed to find paragraph: ${error.message}`);\n }\n}\n\n// Pure helper \u2013 build text style update request\nfunction buildUpdateTextStyleRequest(\n startIndex: number,\n endIndex: number,\n style: {\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n strikethrough?: boolean;\n fontSize?: number;\n fontFamily?: string;\n foregroundColor?: string;\n backgroundColor?: string;\n linkUrl?: string;\n }\n): { request: any; fields: string[] } | null {\n const textStyle: any = {};\n const fieldsToUpdate: string[] = [];\n\n if (style.bold !== undefined) { textStyle.bold = style.bold; fieldsToUpdate.push('bold'); }\n if (style.italic !== undefined) { textStyle.italic = style.italic; fieldsToUpdate.push('italic'); }\n if (style.underline !== undefined) { textStyle.underline = style.underline; fieldsToUpdate.push('underline'); }\n if (style.strikethrough !== undefined) { textStyle.strikethrough = style.strikethrough; fieldsToUpdate.push('strikethrough'); }\n if (style.fontSize !== undefined) { textStyle.fontSize = { magnitude: style.fontSize, unit: 'PT' }; fieldsToUpdate.push('fontSize'); }\n if (style.fontFamily !== undefined) { textStyle.weightedFontFamily = { fontFamily: style.fontFamily }; fieldsToUpdate.push('weightedFontFamily'); }\n\n if (style.foregroundColor !== undefined) {\n const rgbColor = hexToRgbColor(style.foregroundColor);\n if (!rgbColor) throw new Error(`Invalid foreground hex color: ${style.foregroundColor}`);\n textStyle.foregroundColor = { color: { rgbColor } };\n fieldsToUpdate.push('foregroundColor');\n }\n\n if (style.backgroundColor !== undefined) {\n const rgbColor = hexToRgbColor(style.backgroundColor);\n if (!rgbColor) throw new Error(`Invalid background hex color: ${style.backgroundColor}`);\n textStyle.backgroundColor = { color: { rgbColor } };\n fieldsToUpdate.push('backgroundColor');\n }\n\n if (style.linkUrl !== undefined) {\n textStyle.link = { url: style.linkUrl };\n fieldsToUpdate.push('link');\n }\n\n if (fieldsToUpdate.length === 0) return null;\n\n return {\n request: {\n updateTextStyle: {\n range: { startIndex, endIndex },\n textStyle,\n fields: fieldsToUpdate.join(','),\n }\n },\n fields: fieldsToUpdate\n };\n}\n\n// Pure helper \u2013 build paragraph style update request\nfunction buildUpdateParagraphStyleRequest(\n startIndex: number,\n endIndex: number,\n style: {\n alignment?: 'START' | 'END' | 'CENTER' | 'JUSTIFIED';\n indentStart?: number;\n indentEnd?: number;\n spaceAbove?: number;\n spaceBelow?: number;\n namedStyleType?: string;\n keepWithNext?: boolean;\n }\n): { request: any; fields: string[] } | null {\n const paragraphStyle: any = {};\n const fieldsToUpdate: string[] = [];\n\n if (style.alignment !== undefined) { paragraphStyle.alignment = style.alignment; fieldsToUpdate.push('alignment'); }\n if (style.indentStart !== undefined) { paragraphStyle.indentStart = { magnitude: style.indentStart, unit: 'PT' }; fieldsToUpdate.push('indentStart'); }\n if (style.indentEnd !== undefined) { paragraphStyle.indentEnd = { magnitude: style.indentEnd, unit: 'PT' }; fieldsToUpdate.push('indentEnd'); }\n if (style.spaceAbove !== undefined) { paragraphStyle.spaceAbove = { magnitude: style.spaceAbove, unit: 'PT' }; fieldsToUpdate.push('spaceAbove'); }\n if (style.spaceBelow !== undefined) { paragraphStyle.spaceBelow = { magnitude: style.spaceBelow, unit: 'PT' }; fieldsToUpdate.push('spaceBelow'); }\n if (style.namedStyleType !== undefined) { paragraphStyle.namedStyleType = style.namedStyleType; fieldsToUpdate.push('namedStyleType'); }\n if (style.keepWithNext !== undefined) { paragraphStyle.keepWithNext = style.keepWithNext; fieldsToUpdate.push('keepWithNext'); }\n\n if (fieldsToUpdate.length === 0) return null;\n\n return {\n request: {\n updateParagraphStyle: {\n range: { startIndex, endIndex },\n paragraphStyle,\n fields: fieldsToUpdate.join(','),\n }\n },\n fields: fieldsToUpdate\n };\n}\n\n// Insert an inline image from a URL\nasync function insertInlineImageHelper(\n ctx: ToolContext,\n documentId: string,\n imageUrl: string,\n index: number,\n width?: number,\n height?: number\n): Promise<any> {\n // Validate URL format\n try {\n new URL(imageUrl);\n } catch (_e) {\n throw new Error(`Invalid image URL format: ${imageUrl}`);\n }\n\n const request: any = {\n insertInlineImage: {\n location: { index },\n uri: imageUrl\n }\n };\n\n if (width && height) {\n request.insertInlineImage.objectSize = {\n height: { magnitude: height, unit: 'PT' },\n width: { magnitude: width, unit: 'PT' }\n };\n }\n\n return executeBatchUpdate(ctx, documentId, [request]);\n}\n\n// Image upload moved to ../utils/driveImageUpload.ts.\n\n// ---------------------------------------------------------------------------\n// Comment context extraction helpers\n// ---------------------------------------------------------------------------\n\n/** Context extracted for a single comment (keyed by Drive API comment ID) */\nexport interface CommentContext {\n contextBefore?: string;\n contextAfter?: string;\n startIndex?: number;\n endIndex?: number;\n}\n\n/** A segment of text with its Docs API startIndex */\ninterface TextSegment {\n text: string;\n startIndex: number;\n}\n\n/** Result of building flat text from a Google Doc */\ninterface FlatTextResult {\n flatText: string;\n offsetMap: number[];\n}\n\n// Guard against matching XML elements from distant/unrelated tables or paragraphs\nconst MAX_ROW_XML_DISTANCE = 100_000;\nconst MAX_PARAGRAPH_XML_DISTANCE = 50_000;\nconst MAX_PARAGRAPH_CONTEXT_LENGTH = 300;\n\n/**\n * Build flat text from a Google Doc, tracking each character's Docs API startIndex.\n * Handles paragraphs, tables (including nested), and multi-tab docs.\n */\nexport function buildFlatTextFromDoc(docData: any): FlatTextResult {\n function extractSegments(bodyContent: any[]): TextSegment[] {\n const segs: TextSegment[] = [];\n function fromElements(elements: any[]) {\n for (const el of elements) {\n if (el.textRun?.content && el.startIndex != null) {\n segs.push({ text: el.textRun.content, startIndex: el.startIndex });\n }\n }\n }\n for (const el of bodyContent) {\n if (el.paragraph?.elements) {\n fromElements(el.paragraph.elements);\n } else if (el.table) {\n for (const row of el.table.tableRows || []) {\n for (const cell of row.tableCells || []) {\n for (const cc of cell.content || []) {\n if (cc.paragraph?.elements) fromElements(cc.paragraph.elements);\n if (cc.table) {\n const nested = extractSegments([cc]);\n segs.push(...nested);\n }\n }\n }\n }\n }\n }\n return segs;\n }\n\n const allSegments: TextSegment[] = [];\n const tabs = (docData as any).tabs as any[] | undefined;\n if (tabs && tabs.length > 0) {\n for (const tab of tabs) {\n const bc = tab.documentTab?.body?.content;\n if (bc) allSegments.push(...extractSegments(bc));\n }\n } else if (docData.body?.content) {\n allSegments.push(...extractSegments(docData.body.content));\n }\n\n let flatText = '';\n const offsetMap: number[] = [];\n for (const seg of allSegments) {\n for (let i = 0; i < seg.text.length; i++) {\n offsetMap.push(seg.startIndex + i);\n flatText += seg.text[i];\n }\n }\n\n return { flatText, offsetMap };\n}\n\n/** Extract cell texts from a DOCX table row XML string */\nexport function extractRowCells(rowXml: string): string[] {\n const cells: string[] = [];\n let searchFrom = 0;\n while (true) {\n const tcStart1 = rowXml.indexOf('<w:tc>', searchFrom);\n const tcStart2 = rowXml.indexOf('<w:tc ', searchFrom);\n const tcStart = (tcStart1 === -1 && tcStart2 === -1) ? -1 :\n (tcStart1 === -1) ? tcStart2 : (tcStart2 === -1) ? tcStart1 : Math.min(tcStart1, tcStart2);\n if (tcStart === -1) break;\n const tcEnd = rowXml.indexOf('</w:tc>', tcStart);\n if (tcEnd === -1) break;\n const cellXml = rowXml.substring(tcStart, tcEnd);\n const tTexts: string[] = [];\n const tRegex = /<w:t[^>]*>([^<]*)<\\/w:t>/g;\n let t: RegExpExecArray | null;\n while ((t = tRegex.exec(cellXml)) !== null) tTexts.push(t[1]);\n if (tTexts.length > 0) cells.push(tTexts.join(''));\n searchFrom = tcEnd + 7;\n }\n return cells;\n}\n\n/** DOCX comment info parsed from word/comments.xml */\nexport interface DocxComment {\n author: string;\n date: string;\n content: string;\n}\n\n/** Context extracted from DOCX comment ranges in document.xml */\nexport interface DocxContextResult {\n docxComments: Map<number, DocxComment>;\n contextsBefore: Map<number, string>;\n contextsAfter: Map<number, string>;\n rowCells: Map<number, string[]>;\n}\n\n/**\n * Parse a DOCX export to extract comment positions and surrounding context.\n * Returns DOCX comment metadata and context maps keyed by DOCX comment ID.\n */\nexport async function resolveContextFromDocx(docxData: ArrayBuffer): Promise<DocxContextResult | null> {\n const zip = await JSZip.loadAsync(docxData);\n const commentsXml = await zip.file('word/comments.xml')?.async('string');\n const documentXml = await zip.file('word/document.xml')?.async('string');\n\n if (!commentsXml || !documentXml) return null;\n\n // \u2500\u2500 Parse word/comments.xml \u2500\u2500\n const docxComments = new Map<number, DocxComment>();\n const commentTagRegex = /<w:comment\\s+[^>]*?w:id=\"(\\d+)\"[^>]*>/g;\n let cMatch: RegExpExecArray | null;\n while ((cMatch = commentTagRegex.exec(commentsXml)) !== null) {\n const id = parseInt(cMatch[1]);\n const tagStr = cMatch[0];\n const authorMatch = tagStr.match(/w:author=\"([^\"]*)\"/);\n const dateMatch = tagStr.match(/w:date=\"([^\"]*)\"/);\n const author = authorMatch ? authorMatch[1] : '';\n const date = dateMatch ? dateMatch[1] : '';\n\n const endPos = commentsXml.indexOf('</w:comment>', cMatch.index);\n if (endPos !== -1) {\n const body = commentsXml.substring(cMatch.index, endPos);\n const texts: string[] = [];\n const tRegex = /<w:t[^>]*>([^<]*)<\\/w:t>/g;\n let tMatch: RegExpExecArray | null;\n while ((tMatch = tRegex.exec(body)) !== null) {\n texts.push(tMatch[1]);\n }\n docxComments.set(id, { author, date, content: texts.join('') });\n }\n }\n\n // \u2500\u2500 Parse document.xml for comment range context \u2500\u2500\n const contextsBefore = new Map<number, string>();\n const contextsAfter = new Map<number, string>();\n const rowCells = new Map<number, string[]>();\n\n const rangeStartRegex = /<w:commentRangeStart\\s+w:id=\"(\\d+)\"\\/>/g;\n let rMatch: RegExpExecArray | null;\n while ((rMatch = rangeStartRegex.exec(documentXml)) !== null) {\n const docxId = parseInt(rMatch[1]);\n const startPos = rMatch.index;\n\n // Try table row context first (most comments in table-based docs)\n const trStart = documentXml.lastIndexOf('<w:tr>', startPos);\n const trEnd = documentXml.indexOf('</w:tr>', startPos);\n if (trStart !== -1 && trEnd !== -1 && (startPos - trStart) < MAX_ROW_XML_DISTANCE) {\n const rowXml = documentXml.substring(trStart, trEnd);\n\n const cellTexts = extractRowCells(rowXml);\n // Find which cell contains the comment marker\n const commentMarker = `commentRangeStart w:id=\"${docxId}\"`;\n let commentCellIdx = -1;\n let cellSearchFrom = 0;\n for (let ci = 0; ci < cellTexts.length; ci++) {\n // Walk through <w:tc> tags in order to match cell index with extractRowCells output\n const tcStart1 = rowXml.indexOf('<w:tc>', cellSearchFrom);\n const tcStart2 = rowXml.indexOf('<w:tc ', cellSearchFrom);\n const tcStart = (tcStart1 === -1 && tcStart2 === -1) ? -1 :\n (tcStart1 === -1) ? tcStart2 : (tcStart2 === -1) ? tcStart1 : Math.min(tcStart1, tcStart2);\n if (tcStart === -1) break;\n const tcEnd = rowXml.indexOf('</w:tc>', tcStart);\n if (tcEnd === -1) break;\n const cellXml = rowXml.substring(tcStart, tcEnd);\n if (cellXml.includes(commentMarker)) {\n commentCellIdx = ci;\n }\n cellSearchFrom = tcEnd + 7;\n }\n\n if (cellTexts.length > 0) {\n const allTexts = cellTexts;\n rowCells.set(docxId, allTexts);\n\n if (commentCellIdx !== -1) {\n const before = cellTexts.slice(0, commentCellIdx);\n let after = cellTexts.slice(commentCellIdx + 1);\n\n // If comment is in the last cell, grab the NEXT row for \"after\" context\n if (commentCellIdx === cellTexts.length - 1) {\n const nextTrStart = documentXml.indexOf('<w:tr>', trEnd);\n const nextTrEnd = nextTrStart !== -1 ? documentXml.indexOf('</w:tr>', nextTrStart) : -1;\n if (nextTrStart !== -1 && nextTrEnd !== -1) {\n const nextRowXml = documentXml.substring(nextTrStart, nextTrEnd);\n after = extractRowCells(nextRowXml);\n }\n }\n\n const commentText = cellTexts[commentCellIdx];\n contextsBefore.set(docxId, [...before, commentText].join(' | '));\n contextsAfter.set(docxId, [commentText, ...after].join(' | '));\n } else {\n contextsBefore.set(docxId, allTexts.join(' | '));\n contextsAfter.set(docxId, '');\n }\n continue;\n }\n }\n\n // Paragraph fallback for non-table docs\n const pStart = documentXml.lastIndexOf('<w:p ', startPos);\n const pEnd = documentXml.indexOf('</w:p>', startPos);\n if (pStart !== -1 && pEnd !== -1 && (startPos - pStart) < MAX_PARAGRAPH_XML_DISTANCE) {\n const pXml = documentXml.substring(pStart, pEnd);\n const pTexts: string[] = [];\n const tRegex = /<w:t[^>]*>([^<]*)<\\/w:t>/g;\n let t: RegExpExecArray | null;\n while ((t = tRegex.exec(pXml)) !== null) pTexts.push(t[1]);\n const pText = pTexts.join('').trim();\n if (pText) {\n contextsBefore.set(docxId, pText.length > MAX_PARAGRAPH_CONTEXT_LENGTH\n ? pText.substring(0, MAX_PARAGRAPH_CONTEXT_LENGTH) + '...' : pText);\n contextsAfter.set(docxId, '');\n }\n }\n }\n\n return { docxComments, contextsBefore, contextsAfter, rowCells };\n}\n\n/**\n * Match Drive API comments to DOCX comments by (author, createdTime).\n * DOCX timestamps omit milliseconds, so we strip them from the API date.\n * Populates the contextMap with matched context. Also resolves Docs API\n * character offsets when flatText/offsetMap are available.\n */\nexport function matchDocxToDriveComments(\n driveComments: any[],\n docxResult: DocxContextResult,\n contextMap: Map<string, CommentContext>,\n flatText: string,\n offsetMap: number[],\n): void {\n const { docxComments, contextsBefore, contextsAfter } = docxResult;\n\n for (const comment of driveComments) {\n if (contextMap.has(comment.id)) continue; // already has Tier 1 context\n if (comment.resolved) continue; // resolved comments not in DOCX\n\n const apiAuthor = comment.author?.displayName || '';\n const apiDate = (comment.createdTime || '').replace(/\\.\\d+Z$/, 'Z');\n\n // Find matching DOCX comment\n let matchedDocxId: number | null = null;\n for (const [docxId, docxComment] of docxComments) {\n if (docxComment.author === apiAuthor && docxComment.date === apiDate) {\n matchedDocxId = docxId;\n break;\n }\n }\n\n if (matchedDocxId !== null) {\n const ctxBefore = contextsBefore.get(matchedDocxId) || '';\n const ctxAfter = contextsAfter.get(matchedDocxId) || '';\n if (ctxBefore || ctxAfter) {\n const entry: CommentContext = {\n contextBefore: ctxBefore,\n contextAfter: ctxAfter,\n };\n\n // Find Docs API character index using row context in flatText\n const quoted = comment.quotedFileContent?.value;\n if (quoted && flatText && offsetMap.length > 0 && ctxBefore) {\n const beforePattern = ctxBefore.split(' | ').join('\\n');\n\n const findAll = (pattern: string): number[] => {\n const results: number[] = [];\n let from = 0;\n while (true) {\n const idx = flatText.indexOf(pattern, from);\n if (idx === -1) break;\n results.push(idx);\n from = idx + 1;\n }\n return results;\n };\n\n let matches = findAll(beforePattern);\n\n if (matches.length !== 1 && ctxAfter) {\n const afterCells = ctxAfter.split(' | ');\n const afterWithoutAnchor = afterCells.slice(1).join('\\n');\n if (afterWithoutAnchor) {\n const fullPattern = beforePattern + '\\n' + afterWithoutAnchor;\n matches = findAll(fullPattern);\n }\n }\n\n if (matches.length === 1) {\n const patternStart = matches[0];\n const qIdx = patternStart + beforePattern.length - quoted.length;\n const endIdx = qIdx + quoted.length - 1;\n if (endIdx < offsetMap.length && flatText.substring(qIdx, qIdx + quoted.length) === quoted) {\n entry.startIndex = offsetMap[qIdx];\n entry.endIndex = offsetMap[endIdx] + 1;\n }\n }\n }\n\n contextMap.set(comment.id, entry);\n }\n // Remove from map so duplicate timestamps (rare) don't double-match\n docxComments.delete(matchedDocxId);\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Zod schemas\n// ---------------------------------------------------------------------------\n\nconst CreateGoogleDocSchema = z.object({\n name: z.string().min(1, \"Document name is required\"),\n content: z.string(),\n parentFolderId: z.string().optional()\n});\n\nconst UpdateGoogleDocSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n content: z.string()\n});\n\nconst GetGoogleDocContentSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n includeFormatting: z.boolean().optional(),\n});\n\nconst InsertTextSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n text: z.string().min(1, \"Text to insert is required\"),\n index: z.number().int().min(1, \"Index must be at least 1 (1-based)\")\n});\n\nconst DeleteRangeSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n startIndex: z.number().int().min(1, \"Start index must be at least 1\"),\n endIndex: z.number().int().min(1, \"End index must be at least 1\")\n}).refine(data => data.endIndex > data.startIndex, {\n message: \"End index must be greater than start index\",\n path: [\"endIndex\"]\n});\n\nconst ReadGoogleDocSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n format: z.enum(['text', 'json', 'markdown']).optional().default('text'),\n maxLength: z.number().int().min(1).optional(),\n tabId: z.string().optional()\n});\n\nconst ListDocumentTabsSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n includeContent: z.boolean().optional().default(false)\n});\n\nconst ApplyTextStyleSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n startIndex: z.number().int().min(1).optional(),\n endIndex: z.number().int().min(1).optional(),\n textToFind: z.string().min(1).optional(),\n matchInstance: z.number().int().min(1).optional().default(1),\n bold: z.boolean().optional(),\n italic: z.boolean().optional(),\n underline: z.boolean().optional(),\n strikethrough: z.boolean().optional(),\n fontSize: z.number().min(1).optional(),\n fontFamily: z.string().optional(),\n foregroundColor: z.string().optional(),\n backgroundColor: z.string().optional(),\n linkUrl: z.string().url().optional()\n});\n\nconst ApplyParagraphStyleSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n startIndex: z.number().int().min(1).optional(),\n endIndex: z.number().int().min(1).optional(),\n textToFind: z.string().min(1).optional(),\n matchInstance: z.number().int().min(1).optional().default(1),\n indexWithinParagraph: z.number().int().min(1).optional(),\n alignment: z.enum(['START', 'END', 'CENTER', 'JUSTIFIED']).optional(),\n indentStart: z.number().min(0).optional(),\n indentEnd: z.number().min(0).optional(),\n spaceAbove: z.number().min(0).optional(),\n spaceBelow: z.number().min(0).optional(),\n namedStyleType: z.enum(['NORMAL_TEXT', 'TITLE', 'SUBTITLE', 'HEADING_1', 'HEADING_2', 'HEADING_3', 'HEADING_4', 'HEADING_5', 'HEADING_6']).optional(),\n keepWithNext: z.boolean().optional()\n});\n\nconst CreateParagraphBulletsSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n startIndex: z.number().int().min(1).optional(),\n endIndex: z.number().int().min(1).optional(),\n textToFind: z.string().min(1).optional(),\n matchInstance: z.number().int().min(1).optional().default(1),\n bulletPreset: z.enum([\n 'BULLET_DISC_CIRCLE_SQUARE',\n 'BULLET_DIAMONDX_ARROW3D_SQUARE',\n 'BULLET_CHECKBOX',\n 'BULLET_ARROW_DIAMOND_DISC',\n 'BULLET_STAR_CIRCLE_SQUARE',\n 'BULLET_ARROW3D_CIRCLE_SQUARE',\n 'BULLET_LEFTTRIANGLE_DIAMOND_DISC',\n 'NUMBERED_DECIMAL_ALPHA_ROMAN',\n 'NUMBERED_DECIMAL_ALPHA_ROMAN_PARENS',\n 'NUMBERED_DECIMAL_NESTED',\n 'NUMBERED_UPPERALPHA_ALPHA_ROMAN',\n 'NUMBERED_UPPERROMAN_UPPERALPHA_DECIMAL',\n 'NUMBERED_ZERODECIMAL_ALPHA_ROMAN',\n 'NONE'\n ]).default('BULLET_DISC_CIRCLE_SQUARE')\n});\n\nconst ListCommentsSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n includeDeleted: z.boolean().optional(),\n pageSize: z.number().int().min(1).max(100).optional(),\n pageToken: z.string().optional(),\n});\n\nconst GetCommentSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n commentId: z.string().min(1, \"Comment ID is required\")\n});\n\nconst AddCommentSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n startIndex: z.number().int().min(1, \"Start index must be at least 1\"),\n endIndex: z.number().int().min(1, \"End index must be at least 1\"),\n commentText: z.string().min(1, \"Comment text is required\")\n});\n\nconst ReplyToCommentSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n commentId: z.string().min(1, \"Comment ID is required\"),\n replyText: z.string().min(1, \"Reply text is required\"),\n resolve: z.boolean().optional().describe(\"Set to true to resolve the comment thread after replying\")\n});\n\nconst DeleteCommentSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n commentId: z.string().min(1, \"Comment ID is required\")\n});\n\nconst InsertTableSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n rows: z.number().int().min(1, \"Must have at least 1 row\"),\n columns: z.number().int().min(1, \"Must have at least 1 column\"),\n index: z.number().int().min(1, \"Index must be at least 1 (1-based)\")\n});\n\nconst EditTableCellSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n tableStartIndex: z.number().int().min(1, \"Table start index is required\"),\n rowIndex: z.number().int().min(0, \"Row index must be at least 0 (0-based)\"),\n columnIndex: z.number().int().min(0, \"Column index must be at least 0 (0-based)\"),\n textContent: z.string().optional().describe(\"New text content for the cell\"),\n bold: z.boolean().optional(),\n italic: z.boolean().optional(),\n fontSize: z.number().optional(),\n alignment: z.enum([\"START\", \"CENTER\", \"END\", \"JUSTIFIED\"]).optional()\n});\n\nconst InsertImageFromUrlSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n imageUrl: z.string().url(\"Must be a valid URL\"),\n index: z.number().int().min(1, \"Index must be at least 1 (1-based)\"),\n width: z.number().optional().describe(\"Width in points\"),\n height: z.number().optional().describe(\"Height in points\")\n});\n\nconst InsertLocalImageSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n localImagePath: z.string().min(1, \"Local image path is required\"),\n index: z.number().int().min(1, \"Index must be at least 1 (1-based)\"),\n width: z.number().optional().describe(\"Width in points\"),\n height: z.number().optional().describe(\"Height in points\"),\n uploadToSameFolder: z.boolean().optional().default(true).describe(\"Upload to same folder as document\"),\n makePublic: z.boolean().optional().default(false).describe(\"Make uploaded image publicly accessible. Required if the document is not shared with the service account.\")\n});\n\nconst ListGoogleDocsSchema = z.object({\n maxResults: z.number().int().min(1).max(100).optional().default(20).describe(\"Maximum number of documents to return (1-100).\"),\n query: z.string().optional().describe(\"Search query to filter documents by name or content.\"),\n orderBy: z.enum([\"name\", \"modifiedTime\", \"createdTime\"]).optional().default(\"modifiedTime\").describe(\"Sort order for results.\")\n});\n\nconst GetDocumentInfoSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\")\n});\n\nconst FindAndReplaceInDocSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n findText: z.string().min(1, \"findText is required\"),\n replaceText: z.string(),\n matchCase: z.boolean().optional().default(false),\n dryRun: z.boolean().optional().default(false),\n});\n\nconst AddDocumentTabSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n title: z.string().min(1, \"Tab title is required\"),\n});\n\nconst RenameDocumentTabSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n tabId: z.string().min(1, \"Tab ID is required\"),\n title: z.string().min(1, \"Tab title is required\"),\n});\n\nconst InsertSmartChipSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n index: z.number().int().min(1, \"Index must be at least 1\"),\n chipType: z.enum([\"person\"]),\n personEmail: z.string().email(\"Valid email is required for person chip\"),\n});\n\nconst ReadSmartChipsSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n});\n\nconst CreateFootnoteSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n index: z.number().int().min(1, \"Index must be at least 1\").optional(),\n endOfSegment: z.boolean().optional(),\n content: z.string().optional(),\n}).refine(data => data.index !== undefined || data.endOfSegment === true, {\n message: \"Either 'index' or 'endOfSegment: true' must be provided\",\n});\n\n// ---------------------------------------------------------------------------\n// Tool definitions\n// ---------------------------------------------------------------------------\n\nexport const toolDefinitions: ToolDefinition[] = [\n {\n name: \"createGoogleDoc\",\n description: \"Create a new Google Doc\",\n inputSchema: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"Doc name\" },\n content: { type: \"string\", description: \"Doc content\" },\n parentFolderId: { type: \"string\", description: \"Parent folder ID\" }\n },\n required: [\"name\", \"content\"]\n }\n },\n {\n name: \"updateGoogleDoc\",\n description: \"Update an existing Google Doc\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"Doc ID\" },\n content: { type: \"string\", description: \"New content\" }\n },\n required: [\"documentId\", \"content\"]\n }\n },\n {\n name: \"insertText\",\n description: \"Insert text at a specific index in a Google Doc (surgical edit, doesn't replace entire doc)\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"The document ID\" },\n text: { type: \"string\", description: \"Text to insert\" },\n index: { type: \"number\", description: \"Position to insert at (1-based)\" }\n },\n required: [\"documentId\", \"text\", \"index\"]\n }\n },\n {\n name: \"deleteRange\",\n description: \"Delete content between start and end indices in a Google Doc\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"The document ID\" },\n startIndex: { type: \"number\", description: \"Start index (1-based, inclusive)\" },\n endIndex: { type: \"number\", description: \"End index (exclusive)\" }\n },\n required: [\"documentId\", \"startIndex\", \"endIndex\"]\n }\n },\n {\n name: \"readGoogleDoc\",\n description: \"Read content of a Google Doc with format options. Supports multi-tab documents.\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"The document ID\" },\n format: { type: \"string\", enum: [\"text\", \"json\", \"markdown\"], description: \"Output format (default: text)\" },\n maxLength: { type: \"number\", description: \"Maximum characters to return\" },\n tabId: { type: \"string\", description: \"Read a specific tab by ID (from listDocumentTabs). If omitted, all tabs are returned.\" }\n },\n required: [\"documentId\"]\n }\n },\n {\n name: \"listDocumentTabs\",\n description: \"List all tabs in a Google Doc with their IDs and hierarchy\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"The document ID\" },\n includeContent: { type: \"boolean\", description: \"Include content summary (character count) for each tab\" }\n },\n required: [\"documentId\"]\n }\n },\n {\n name: \"applyTextStyle\",\n description: \"Apply text formatting (bold, italic, color, etc.) to a range or found text. Use EITHER startIndex+endIndex OR textToFind for targeting.\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"The document ID\" },\n startIndex: { type: \"number\", description: \"Start index (1-based) - use with endIndex\" },\n endIndex: { type: \"number\", description: \"End index (exclusive) - use with startIndex\" },\n textToFind: { type: \"string\", description: \"Text to find and format (alternative to indices)\" },\n matchInstance: { type: \"number\", description: \"Which instance of textToFind (default: 1)\" },\n bold: { type: \"boolean\", description: \"Make text bold\" },\n italic: { type: \"boolean\", description: \"Make text italic\" },\n underline: { type: \"boolean\", description: \"Underline text\" },\n strikethrough: { type: \"boolean\", description: \"Strikethrough text\" },\n fontSize: { type: \"number\", description: \"Font size in points\" },\n fontFamily: { type: \"string\", description: \"Font family name\" },\n foregroundColor: { type: \"string\", description: \"Hex color (e.g., #FF0000)\" },\n backgroundColor: { type: \"string\", description: \"Hex background color\" },\n linkUrl: { type: \"string\", description: \"URL for hyperlink\" }\n },\n required: [\"documentId\"]\n }\n },\n {\n name: \"applyParagraphStyle\",\n description: \"Apply paragraph formatting. Use EITHER startIndex+endIndex OR textToFind OR indexWithinParagraph for targeting.\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"The document ID\" },\n startIndex: { type: \"number\", description: \"Start index (1-based) - use with endIndex\" },\n endIndex: { type: \"number\", description: \"End index (exclusive) - use with startIndex\" },\n textToFind: { type: \"string\", description: \"Text within the target paragraph\" },\n matchInstance: { type: \"number\", description: \"Which instance of textToFind (default: 1)\" },\n indexWithinParagraph: { type: \"number\", description: \"Any index within the target paragraph\" },\n alignment: { type: \"string\", enum: [\"START\", \"END\", \"CENTER\", \"JUSTIFIED\"], description: \"Text alignment\" },\n indentStart: { type: \"number\", description: \"Left indent in points\" },\n indentEnd: { type: \"number\", description: \"Right indent in points\" },\n spaceAbove: { type: \"number\", description: \"Space above in points\" },\n spaceBelow: { type: \"number\", description: \"Space below in points\" },\n namedStyleType: { type: \"string\", enum: [\"NORMAL_TEXT\", \"TITLE\", \"SUBTITLE\", \"HEADING_1\", \"HEADING_2\", \"HEADING_3\", \"HEADING_4\", \"HEADING_5\", \"HEADING_6\"], description: \"Named paragraph style\" },\n keepWithNext: { type: \"boolean\", description: \"Keep with next paragraph\" }\n },\n required: [\"documentId\"]\n }\n },\n {\n name: \"formatGoogleDocText\",\n description: \"Apply text formatting (bold, italic, font, color, links) to a range or found text in a Google Doc. Alias for applyTextStyle.\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"The document ID\" },\n startIndex: { type: \"number\", description: \"Start index (1-based) - use with endIndex\" },\n endIndex: { type: \"number\", description: \"End index (exclusive) - use with startIndex\" },\n textToFind: { type: \"string\", description: \"Text to find and format (alternative to indices)\" },\n matchInstance: { type: \"number\", description: \"Which instance of textToFind (default: 1)\" },\n bold: { type: \"boolean\", description: \"Make text bold\" },\n italic: { type: \"boolean\", description: \"Make text italic\" },\n underline: { type: \"boolean\", description: \"Underline text\" },\n strikethrough: { type: \"boolean\", description: \"Strikethrough text\" },\n fontSize: { type: \"number\", description: \"Font size in points\" },\n fontFamily: { type: \"string\", description: \"Font family name\" },\n foregroundColor: { type: \"string\", description: \"Hex color (e.g., #FF0000)\" },\n backgroundColor: { type: \"string\", description: \"Hex background color\" },\n linkUrl: { type: \"string\", description: \"URL for hyperlink\" }\n },\n required: [\"documentId\"]\n }\n },\n {\n name: \"formatGoogleDocParagraph\",\n description: \"Apply paragraph formatting (alignment, indentation, spacing, heading style) in a Google Doc. Alias for applyParagraphStyle.\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"The document ID\" },\n startIndex: { type: \"number\", description: \"Start index (1-based) - use with endIndex\" },\n endIndex: { type: \"number\", description: \"End index (exclusive) - use with startIndex\" },\n textToFind: { type: \"string\", description: \"Text within the target paragraph\" },\n matchInstance: { type: \"number\", description: \"Which instance of textToFind (default: 1)\" },\n indexWithinParagraph: { type: \"number\", description: \"Any index within the target paragraph\" },\n alignment: { type: \"string\", enum: [\"START\", \"END\", \"CENTER\", \"JUSTIFIED\"], description: \"Text alignment\" },\n indentStart: { type: \"number\", description: \"Left indent in points\" },\n indentEnd: { type: \"number\", description: \"Right indent in points\" },\n spaceAbove: { type: \"number\", description: \"Space above in points\" },\n spaceBelow: { type: \"number\", description: \"Space below in points\" },\n namedStyleType: { type: \"string\", enum: [\"NORMAL_TEXT\", \"TITLE\", \"SUBTITLE\", \"HEADING_1\", \"HEADING_2\", \"HEADING_3\", \"HEADING_4\", \"HEADING_5\", \"HEADING_6\"], description: \"Named paragraph style\" },\n keepWithNext: { type: \"boolean\", description: \"Keep with next paragraph\" }\n },\n required: [\"documentId\"]\n }\n },\n {\n name: \"createParagraphBullets\",\n description: \"Add or remove bullet points / numbered lists on paragraphs in a Google Doc. Target paragraphs by startIndex+endIndex or textToFind. Use bulletPreset='NONE' to remove bullets.\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"The document ID\" },\n startIndex: { type: \"number\", description: \"Start index (1-based) - use with endIndex\" },\n endIndex: { type: \"number\", description: \"End index (exclusive) - use with startIndex\" },\n textToFind: { type: \"string\", description: \"Text within the target paragraph(s) to bulletize\" },\n matchInstance: { type: \"number\", description: \"Which instance of textToFind (default: 1)\" },\n bulletPreset: { type: \"string\", enum: [\"BULLET_DISC_CIRCLE_SQUARE\", \"BULLET_DIAMONDX_ARROW3D_SQUARE\", \"BULLET_CHECKBOX\", \"BULLET_ARROW_DIAMOND_DISC\", \"BULLET_STAR_CIRCLE_SQUARE\", \"BULLET_ARROW3D_CIRCLE_SQUARE\", \"BULLET_LEFTTRIANGLE_DIAMOND_DISC\", \"NUMBERED_DECIMAL_ALPHA_ROMAN\", \"NUMBERED_DECIMAL_ALPHA_ROMAN_PARENS\", \"NUMBERED_DECIMAL_NESTED\", \"NUMBERED_UPPERALPHA_ALPHA_ROMAN\", \"NUMBERED_UPPERROMAN_UPPERALPHA_DECIMAL\", \"NUMBERED_ZERODECIMAL_ALPHA_ROMAN\", \"NONE\"], description: \"Bullet style preset. Use NONE to remove bullets. Default: BULLET_DISC_CIRCLE_SQUARE\" }\n },\n required: [\"documentId\"]\n }\n },\n {\n name: \"findAndReplaceInDoc\",\n description: \"Find and replace text across a Google Document. Dry-run mode counts matches from paragraph text only (may differ from actual replacements which cover tables, headers, footers, etc.)\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"The document ID\" },\n findText: { type: \"string\", description: \"Text to find\" },\n replaceText: { type: \"string\", description: \"Replacement text\" },\n matchCase: { type: \"boolean\", description: \"Case-sensitive match (default: false)\" },\n dryRun: { type: \"boolean\", description: \"Only count approximate matches from paragraph text, do not modify document (default: false)\" }\n },\n required: [\"documentId\", \"findText\", \"replaceText\"]\n }\n },\n {\n name: \"listComments\",\n description: \"List all comments in a Google Document\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"The document ID\" },\n includeDeleted: { type: \"boolean\", description: \"Whether to include deleted comments (default: false)\" },\n pageSize: { type: \"number\", description: \"Max comments to return (1-100, default: 100)\" },\n pageToken: { type: \"string\", description: \"Token for next page of results\" },\n },\n required: [\"documentId\"]\n }\n },\n {\n name: \"getComment\",\n description: \"Get a specific comment with its full thread of replies\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"The document ID\" },\n commentId: { type: \"string\", description: \"The comment ID\" }\n },\n required: [\"documentId\", \"commentId\"]\n }\n },\n {\n name: \"addComment\",\n description: \"Add a comment anchored to a specific text range. Note: Due to Google API limitations, programmatic comments appear in 'All Comments' but may not be visibly anchored in the document UI.\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"The document ID\" },\n startIndex: { type: \"number\", description: \"Start index (1-based)\" },\n endIndex: { type: \"number\", description: \"End index (exclusive)\" },\n commentText: { type: \"string\", description: \"The comment content\" }\n },\n required: [\"documentId\", \"startIndex\", \"endIndex\", \"commentText\"]\n }\n },\n {\n name: \"replyToComment\",\n description: \"Add a reply to an existing comment\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"The document ID\" },\n commentId: { type: \"string\", description: \"The comment ID to reply to\" },\n replyText: { type: \"string\", description: \"The reply content\" },\n resolve: { type: \"boolean\", description: \"Set to true to resolve the comment thread after replying (default: false)\" }\n },\n required: [\"documentId\", \"commentId\", \"replyText\"]\n }\n },\n {\n name: \"deleteComment\",\n description: \"Delete a comment from the document\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"The document ID\" },\n commentId: { type: \"string\", description: \"The comment ID to delete\" }\n },\n required: [\"documentId\", \"commentId\"]\n }\n },\n {\n name: \"getGoogleDocContent\",\n description: \"Get content of a Google Doc with text indices for formatting\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"Document ID\" },\n includeFormatting: { type: \"boolean\", description: \"Include font, style, and color info for each text span (default: false)\" },\n },\n required: [\"documentId\"]\n }\n },\n {\n name: \"insertTable\",\n description: \"Insert a new table with the specified dimensions at a given index\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"The document ID\" },\n rows: { type: \"number\", description: \"Number of rows for the new table\" },\n columns: { type: \"number\", description: \"Number of columns for the new table\" },\n index: { type: \"number\", description: \"The index (1-based) where the table should be inserted\" }\n },\n required: [\"documentId\", \"rows\", \"columns\", \"index\"]\n }\n },\n {\n name: \"editTableCell\",\n description: \"Edit the content and/or style of a specific table cell. Requires knowing the table start index.\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"The document ID\" },\n tableStartIndex: { type: \"number\", description: \"The starting index of the TABLE element\" },\n rowIndex: { type: \"number\", description: \"Row index (0-based)\" },\n columnIndex: { type: \"number\", description: \"Column index (0-based)\" },\n textContent: { type: \"string\", description: \"New text content for the cell (replaces existing)\" },\n bold: { type: \"boolean\", description: \"Make text bold\" },\n italic: { type: \"boolean\", description: \"Make text italic\" },\n fontSize: { type: \"number\", description: \"Font size in points\" },\n alignment: { type: \"string\", enum: [\"START\", \"CENTER\", \"END\", \"JUSTIFIED\"], description: \"Text alignment\" }\n },\n required: [\"documentId\", \"tableStartIndex\", \"rowIndex\", \"columnIndex\"]\n }\n },\n {\n name: \"insertImageFromUrl\",\n description: \"Insert an inline image into a Google Document from a publicly accessible URL\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"The document ID\" },\n imageUrl: { type: \"string\", description: \"Publicly accessible URL to the image\" },\n index: { type: \"number\", description: \"The index (1-based) where the image should be inserted\" },\n width: { type: \"number\", description: \"Width of the image in points\" },\n height: { type: \"number\", description: \"Height of the image in points\" }\n },\n required: [\"documentId\", \"imageUrl\", \"index\"]\n }\n },\n {\n name: \"insertLocalImage\",\n description: \"Upload a local image file to Google Drive and insert it into a Google Document\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"The document ID\" },\n localImagePath: { type: \"string\", description: \"Absolute path to the local image file\" },\n index: { type: \"number\", description: \"The index (1-based) where the image should be inserted\" },\n width: { type: \"number\", description: \"Width of the image in points\" },\n height: { type: \"number\", description: \"Height of the image in points\" },\n uploadToSameFolder: { type: \"boolean\", description: \"Upload to same folder as document (default: true)\" },\n makePublic: { type: \"boolean\", description: \"Make uploaded image publicly accessible (anyone with the link can view). Set to true if the Docs API cannot access the image through the authenticated user's permissions. Default: false\" }\n },\n required: [\"documentId\", \"localImagePath\", \"index\"]\n }\n },\n {\n name: \"listGoogleDocs\",\n description: \"Lists Google Documents from your Google Drive with optional filtering.\",\n inputSchema: {\n type: \"object\",\n properties: {\n maxResults: { type: \"integer\", description: \"Maximum number of documents to return (1-100).\" },\n query: { type: \"string\", description: \"Search query to filter documents by name or content.\" },\n orderBy: { type: \"string\", enum: [\"name\", \"modifiedTime\", \"createdTime\"], description: \"Sort order for results.\" }\n },\n required: []\n }\n },\n {\n name: \"getDocumentInfo\",\n description: \"Gets detailed information about a specific Google Document.\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"The ID of the Google Document (from the URL).\" }\n },\n required: [\"documentId\"]\n }\n },\n {\n name: \"addDocumentTab\",\n description: \"Add a new tab in a Google Doc\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"Document ID\" },\n title: { type: \"string\", description: \"Tab title\" }\n },\n required: [\"documentId\", \"title\"]\n }\n },\n {\n name: \"renameDocumentTab\",\n description: \"Rename an existing Google Doc tab\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"Document ID\" },\n tabId: { type: \"string\", description: \"Tab ID\" },\n title: { type: \"string\", description: \"New tab title\" }\n },\n required: [\"documentId\", \"tabId\", \"title\"]\n }\n },\n {\n name: \"insertSmartChip\",\n description: \"Insert a person smart chip (mention) at a document index. Only person chips are supported by the Docs API; date and file chips are read-only.\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"Document ID\" },\n index: { type: \"number\", description: \"Insertion index (1-based)\" },\n chipType: { type: \"string\", enum: [\"person\"], description: \"Smart chip type (only 'person' is supported)\" },\n personEmail: { type: \"string\", description: \"Email address for the person mention\" }\n },\n required: [\"documentId\", \"index\", \"chipType\", \"personEmail\"]\n }\n },\n {\n name: \"readSmartChips\",\n description: \"Read smart chip-like elements (person mentions, rich links, date chips) from the default tab of a document\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"Document ID\" }\n },\n required: [\"documentId\"]\n }\n },\n {\n name: \"createFootnote\",\n description: \"Create a footnote in a Google Doc. Footnotes cannot be inserted inside equations, headers, footers, or other footnotes.\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"Document ID\" },\n index: { type: \"number\", description: \"1-based character index where the footnote reference should be inserted\" },\n endOfSegment: { type: \"boolean\", description: \"If true, insert footnote at the end of the document body (use instead of index)\" },\n content: { type: \"string\", description: \"Optional text content for the footnote body\" },\n },\n required: [\"documentId\"]\n }\n },\n];\n\n// ---------------------------------------------------------------------------\n// Handler\n// ---------------------------------------------------------------------------\n\nexport async function handleTool(toolName: string, args: Record<string, unknown>, ctx: ToolContext): Promise<ToolResult | null> {\n switch (toolName) {\n\n // =========================================================================\n // CREATE / UPDATE GOOGLE DOC\n // =========================================================================\n\n case \"createGoogleDoc\": {\n const validation = CreateGoogleDocSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const parentFolderId = await ctx.resolveFolderId(a.parentFolderId);\n\n // Check if document already exists\n const existingFileId = await ctx.checkFileExists(a.name, parentFolderId);\n if (existingFileId) {\n return errorResponse(\n `A document named \"${a.name}\" already exists in this location. ` +\n `To update it, use updateGoogleDoc with documentId: ${existingFileId}`\n );\n }\n\n // Create empty doc\n let docResponse;\n try {\n docResponse = await ctx.getDrive().files.create({\n requestBody: {\n name: a.name,\n mimeType: 'application/vnd.google-apps.document',\n parents: [parentFolderId]\n },\n fields: 'id, name, webViewLink',\n supportsAllDrives: true\n });\n } catch (createError: any) {\n ctx.log('Drive files.create error details:', {\n message: createError.message,\n code: createError.code,\n errors: createError.errors,\n status: createError.status\n });\n throw createError;\n }\n const doc = docResponse.data;\n\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n await docs.documents.batchUpdate({\n documentId: doc.id!,\n requestBody: {\n requests: [\n {\n insertText: { location: { index: 1 }, text: a.content }\n },\n // Ensure the text is formatted as normal text, not as a header\n {\n updateParagraphStyle: {\n range: {\n startIndex: 1,\n endIndex: a.content.length + 1\n },\n paragraphStyle: {\n namedStyleType: 'NORMAL_TEXT'\n },\n fields: 'namedStyleType'\n }\n }\n ]\n }\n });\n\n return {\n content: [{ type: \"text\", text: `Created Google Doc: ${doc.name}\\nID: ${doc.id}\\nLink: ${doc.webViewLink}` }],\n isError: false\n };\n }\n\n case \"updateGoogleDoc\": {\n const validation = UpdateGoogleDocSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n const document = await docs.documents.get({ documentId: a.documentId });\n\n // Delete all content\n const endIndex = document.data.body?.content?.[document.data.body.content.length - 1]?.endIndex || 1;\n const deleteEndIndex = Math.max(1, endIndex - 1);\n\n if (deleteEndIndex > 1) {\n await docs.documents.batchUpdate({\n documentId: a.documentId,\n requestBody: {\n requests: [{\n deleteContentRange: {\n range: { startIndex: 1, endIndex: deleteEndIndex }\n }\n }]\n }\n });\n }\n\n // Insert new content\n await docs.documents.batchUpdate({\n documentId: a.documentId,\n requestBody: {\n requests: [\n {\n insertText: { location: { index: 1 }, text: a.content }\n },\n {\n updateParagraphStyle: {\n range: {\n startIndex: 1,\n endIndex: a.content.length + 1\n },\n paragraphStyle: {\n namedStyleType: 'NORMAL_TEXT'\n },\n fields: 'namedStyleType'\n }\n }\n ]\n }\n });\n\n return {\n content: [{ type: \"text\", text: `Updated Google Doc: ${document.data.title}` }],\n isError: false\n };\n }\n\n // =========================================================================\n // DOC CONTENT\n // =========================================================================\n\n case \"getGoogleDocContent\": {\n const validation = GetGoogleDocContentSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n const withFormatting = a.includeFormatting === true;\n\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n const document = await docs.documents.get({\n documentId: a.documentId,\n includeTabsContent: true,\n });\n\n interface Segment {\n text: string;\n startIndex: number;\n endIndex: number;\n fontFamily?: string;\n fontSize?: number;\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n strikethrough?: boolean;\n foregroundColor?: string;\n backgroundColor?: string;\n }\n\n // Helper to resolve inline element text for non-textRun elements\n function resolveInlineElementText(el: any, inlineObjects?: any): string | null {\n if (el.person?.personProperties) {\n const p = el.person.personProperties;\n if (p.name && p.email) return `@${p.name} (${p.email})`;\n return `@${p.name || p.email || ''}`;\n }\n if (el.richLink?.richLinkProperties) {\n const rl = el.richLink.richLinkProperties;\n const title = (rl.title || rl.uri || '').replace(/[\\[\\]]/g, '\\\\$&');\n const uri = rl.uri;\n return title && uri ? `[${title}](${uri})` : title || null;\n }\n if (el.inlineObjectElement?.inlineObjectId) {\n if (inlineObjects) {\n const obj = inlineObjects[el.inlineObjectElement.inlineObjectId];\n const desc = obj?.inlineObjectProperties?.embeddedObject?.description\n || obj?.inlineObjectProperties?.embeddedObject?.title;\n return desc ? `[image: ${desc}]` : '[image]';\n }\n return '[image]';\n }\n if (el.footnoteReference) {\n return `[^${el.footnoteReference.footnoteNumber || ''}]`;\n }\n if (el.horizontalRule) {\n return '---\\n';\n }\n return null;\n }\n\n // Helper to extract segments from body content\n // Table cell extraction reuses processContent so that any element handling\n // (inline elements, formatting, etc.) automatically applies inside table\n // cells as well.\n function extractSegments(bodyContent: any[], inlineObjects?: any): Segment[] {\n const segments: Segment[] = [];\n\n // Extract plain text from a table cell by running its content through\n // processContent and collecting the text from the produced segments.\n function getCellText(cellContent: any[]): string {\n const before = segments.length;\n processContent(cellContent);\n const cellSegs = segments.splice(before);\n // Strip trailing newlines, join paragraphs with space, then escape\n // pipe characters so they don't create extra markdown columns.\n return cellSegs\n .map(s => s.text.replace(/\\n$/g, ''))\n .join(' ')\n .replace(/\\|/g, '\\\\|')\n .trim();\n }\n\n function processContent(content: any[]) {\n for (const element of content) {\n if (element.paragraph?.elements) {\n for (const textElement of element.paragraph.elements) {\n if (textElement.textRun?.content && textElement.startIndex != null && textElement.endIndex != null) {\n const seg: Segment = {\n text: textElement.textRun.content,\n startIndex: textElement.startIndex,\n endIndex: textElement.endIndex,\n };\n if (withFormatting) {\n const ts = textElement.textRun.textStyle;\n if (ts) {\n if (ts.weightedFontFamily?.fontFamily) seg.fontFamily = ts.weightedFontFamily.fontFamily;\n if (ts.fontSize?.magnitude != null) seg.fontSize = ts.fontSize.magnitude;\n if (ts.bold) seg.bold = true;\n if (ts.italic) seg.italic = true;\n if (ts.underline) seg.underline = true;\n if (ts.strikethrough) seg.strikethrough = true;\n const fg = rgbColorToHex(ts.foregroundColor);\n const bg = rgbColorToHex(ts.backgroundColor);\n if (fg) seg.foregroundColor = fg;\n if (bg) seg.backgroundColor = bg;\n }\n }\n segments.push(seg);\n } else {\n // Handle non-textRun inline elements (person chips, rich links, images, footnotes, horizontal rules)\n const inlineText = resolveInlineElementText(textElement, inlineObjects);\n if (inlineText && textElement.startIndex != null && textElement.endIndex != null) {\n segments.push({\n text: inlineText,\n startIndex: textElement.startIndex,\n endIndex: textElement.endIndex,\n });\n }\n }\n }\n } else if (element.table?.tableRows) {\n const rows: string[] = [];\n for (let rowIdx = 0; rowIdx < element.table.tableRows.length; rowIdx++) {\n const row = element.table.tableRows[rowIdx];\n if (!row.tableCells) continue;\n const cellTexts: string[] = [];\n for (const cell of row.tableCells) {\n cellTexts.push(cell.content ? getCellText(cell.content) : '');\n }\n rows.push('| ' + cellTexts.join(' | ') + ' |');\n if (rowIdx === 0) {\n rows.push('| ' + cellTexts.map(() => '---').join(' | ') + ' |');\n }\n }\n const md = rows.join('\\n') + '\\n\\n';\n if (element.startIndex != null && element.endIndex != null) {\n segments.push({\n text: md,\n startIndex: element.startIndex,\n endIndex: element.endIndex,\n });\n }\n } else if (element.tableOfContents?.content) {\n processContent(element.tableOfContents.content);\n }\n }\n }\n\n processContent(bodyContent);\n return segments;\n }\n\n // Helper to format segments into indexed text\n function formatSegments(segments: Segment[]): string {\n let result = '';\n for (const segment of segments) {\n const hasMeta = withFormatting && hasFormattingInfo(segment);\n const meta = hasMeta ? buildMetaLine(segment) : null;\n const lines = segment.text.split('\\n');\n let offset = segment.startIndex;\n for (const line of lines) {\n if (line.trim()) {\n if (meta) {\n result += `[${offset}-${offset + line.length}] ${meta}\\n ${line}\\n`;\n } else {\n result += `[${offset}-${offset + line.length}] ${line}\\n`;\n }\n }\n offset += line.length + 1;\n }\n }\n return result;\n }\n\n function hasFormattingInfo(seg: Segment): boolean {\n return !!(seg.fontFamily || seg.fontSize || seg.bold || seg.italic || seg.underline || seg.strikethrough || seg.foregroundColor || seg.backgroundColor);\n }\n\n function buildMetaLine(seg: Segment): string {\n const parts: string[] = [];\n if (seg.fontFamily) parts.push(`font=\"${seg.fontFamily}\"`);\n if (seg.fontSize) parts.push(`size=${seg.fontSize}pt`);\n const styles: string[] = [];\n if (seg.bold) styles.push('bold');\n if (seg.italic) styles.push('italic');\n if (seg.underline) styles.push('underline');\n if (seg.strikethrough) styles.push('strikethrough');\n if (styles.length > 0) parts.push(`style=${styles.join(',')}`);\n if (seg.foregroundColor) parts.push(`color=${seg.foregroundColor}`);\n if (seg.backgroundColor) parts.push(`bg=${seg.backgroundColor}`);\n return parts.join(', ');\n }\n\n // Accumulate font usage across all segments\n interface FontInfo { sizes: Set<number>; styles: Set<string>; charCount: number }\n const fontUsage: Map<string, FontInfo> = new Map();\n function trackFonts(segments: Segment[]) {\n if (!withFormatting) return;\n for (const seg of segments) {\n if (seg.fontFamily) {\n let info = fontUsage.get(seg.fontFamily);\n if (!info) {\n info = { sizes: new Set(), styles: new Set(), charCount: 0 };\n fontUsage.set(seg.fontFamily, info);\n }\n if (seg.fontSize) info.sizes.add(seg.fontSize);\n if (seg.bold) info.styles.add('bold');\n if (seg.italic) info.styles.add('italic');\n if (seg.underline) info.styles.add('underline');\n if (seg.strikethrough) info.styles.add('strikethrough');\n info.charCount += seg.endIndex - seg.startIndex;\n }\n }\n }\n\n const tabs = (document.data as any).tabs as any[] | undefined;\n let formattedContent = 'Document content with indices:\\n\\n';\n let totalLength = 0;\n\n if (tabs && tabs.length > 0) {\n const allTabs = collectAllTabsWithLevel(tabs);\n const isMultiTab = allTabs.length > 1;\n for (const { tab, level } of allTabs) {\n const bodyContent = tab.documentTab?.body?.content;\n // Multi-tab: include all tabs with headers\n if (isMultiTab) {\n const title = tab.tabProperties?.title || 'Untitled';\n const indent = ' '.repeat(level);\n formattedContent += `${indent}=== Tab: ${title} ===\\n`;\n }\n if (bodyContent) {\n const tabInlineObjects = tab.documentTab?.inlineObjects;\n const segments = extractSegments(bodyContent, tabInlineObjects);\n trackFonts(segments);\n formattedContent += formatSegments(segments);\n if (segments.length > 0) {\n totalLength += segments[segments.length - 1].endIndex;\n }\n }\n // Multi-tab: add new line between tabs\n if (isMultiTab) {\n formattedContent += '\\n';\n }\n }\n } else {\n // Fallback to legacy body content\n const bodyContent = document.data.body?.content;\n if (bodyContent) {\n const legacyInlineObjects = (document.data as any).inlineObjects;\n const segments = extractSegments(bodyContent, legacyInlineObjects);\n trackFonts(segments);\n formattedContent += formatSegments(segments);\n totalLength = segments.length > 0 ? segments[segments.length - 1].endIndex : 0;\n }\n }\n\n if (withFormatting && fontUsage.size > 0) {\n formattedContent += '\\n--- Fonts summary ---\\n';\n const sorted = [...fontUsage.entries()].sort((a, b) => b[1].charCount - a[1].charCount);\n for (const [font, info] of sorted) {\n const sizesStr = info.sizes.size > 0 ? [...info.sizes].sort((a, b) => a - b).join(', ') + ' pt' : 'default size';\n const stylesStr = info.styles.size > 0 ? [...info.styles].sort().join(', ') : 'normal';\n formattedContent += `${font}: sizes [${sizesStr}], styles [${stylesStr}], ~${info.charCount} chars\\n`;\n }\n }\n\n return {\n content: [{\n type: \"text\",\n text: formattedContent + `\\nTotal length: ${totalLength} characters`\n }],\n isError: false\n };\n }\n\n // =========================================================================\n // DOC EDITING TOOLS\n // =========================================================================\n\n case \"insertText\": {\n const validation = InsertTextSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n await docs.documents.batchUpdate({\n documentId: a.documentId,\n requestBody: {\n requests: [{\n insertText: {\n location: { index: a.index },\n text: a.text\n }\n }]\n }\n });\n\n return {\n content: [{ type: \"text\", text: `Successfully inserted ${a.text.length} characters at index ${a.index}` }],\n isError: false\n };\n }\n\n case \"deleteRange\": {\n const validation = DeleteRangeSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n if (a.endIndex <= a.startIndex) {\n return errorResponse(\"endIndex must be greater than startIndex\");\n }\n\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n await docs.documents.batchUpdate({\n documentId: a.documentId,\n requestBody: {\n requests: [{\n deleteContentRange: {\n range: {\n startIndex: a.startIndex,\n endIndex: a.endIndex\n }\n }\n }]\n }\n });\n\n return {\n content: [{ type: \"text\", text: `Successfully deleted content from index ${a.startIndex} to ${a.endIndex}` }],\n isError: false\n };\n }\n\n case \"readGoogleDoc\": {\n const validation = ReadGoogleDocSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n const docResponse = await docs.documents.get({\n documentId: a.documentId,\n includeTabsContent: true,\n });\n\n const doc = docResponse.data;\n const format = a.format || 'text';\n\n if (format === 'json') {\n let result = JSON.stringify(doc, null, 2);\n if (a.maxLength && result.length > a.maxLength) {\n result = result.substring(0, a.maxLength) + '\\n... (truncated)';\n }\n return {\n content: [{ type: \"text\", text: result }],\n isError: false\n };\n }\n\n // Helper to extract plain text from body content\n function extractText(bodyContent: any[]): string {\n let result = '';\n for (const element of bodyContent) {\n if (element.paragraph?.elements) {\n for (const elem of element.paragraph.elements) {\n if (elem.textRun?.content) {\n result += elem.textRun.content;\n }\n }\n } else if (element.table) {\n for (const row of element.table.tableRows || []) {\n for (const cell of row.tableCells || []) {\n for (const cellContent of cell.content || []) {\n if (cellContent.paragraph?.elements) {\n for (const elem of cellContent.paragraph.elements) {\n if (elem.textRun?.content) {\n result += elem.textRun.content;\n }\n }\n }\n }\n result += '\\t';\n }\n result += '\\n';\n }\n }\n }\n return result;\n }\n\n let text = '';\n const tabs = (doc as any).tabs as any[] | undefined;\n\n if (tabs && tabs.length > 0) {\n if (a.tabId) {\n // Find the specific tab (recursively through childTabs)\n const tab = findTabById(tabs, a.tabId);\n if (!tab) {\n return errorResponse(`Tab with ID \"${a.tabId}\" not found. Use listDocumentTabs to see available tabs.`);\n }\n const bodyContent = tab.documentTab?.body?.content;\n if (bodyContent) {\n text = extractText(bodyContent);\n }\n } else {\n const allTabs = collectAllTabsWithLevel(tabs);\n const isMultiTab = allTabs.length > 1;\n for (const { tab, level } of allTabs) {\n const bodyContent = tab.documentTab?.body?.content;\n // Multi-tab: include all tabs with headers\n if (isMultiTab) {\n const title = tab.tabProperties?.title || 'Untitled';\n const indent = ' '.repeat(level);\n text += `${indent}=== Tab: ${title} ===\\n`;\n }\n if (bodyContent) {\n text += extractText(bodyContent);\n }\n // Multi-tab: add new line between tabs\n if (isMultiTab) {\n text += '\\n';\n }\n }\n }\n } else {\n // Fallback to legacy body content\n const body = doc.body;\n if (body?.content) {\n text = extractText(body.content);\n }\n }\n\n if (format === 'markdown') {\n text = `# ${doc.title}\\n\\n${text}`;\n }\n\n if (a.maxLength && text.length > a.maxLength) {\n text = text.substring(0, a.maxLength) + '\\n... (truncated)';\n }\n\n return {\n content: [{ type: \"text\", text }],\n isError: false\n };\n }\n\n case \"listDocumentTabs\": {\n const validation = ListDocumentTabsSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n // Use includeTabsContent to get the new tabs structure\n const docResponse = await docs.documents.get({\n documentId: a.documentId,\n includeTabsContent: true\n });\n\n const doc = docResponse.data;\n\n // Check if document has tabs (newer API feature)\n const tabs = (doc as any).tabs;\n if (!tabs || tabs.length === 0) {\n // Single-tab document or legacy format - check for body content\n let contentInfo = '';\n if (a.includeContent) {\n let charCount = 0;\n const body = doc.body;\n if (body?.content) {\n for (const element of body.content) {\n if (element.paragraph?.elements) {\n for (const elem of element.paragraph.elements) {\n if (elem.textRun?.content) {\n charCount += elem.textRun.content.length;\n }\n }\n }\n }\n }\n contentInfo = ` (${charCount} characters)`;\n }\n return {\n content: [{ type: \"text\", text: `Document \"${doc.title}\" has a single tab (standard format).${contentInfo}` }],\n isError: false\n };\n }\n\n // Process tabs\n const processTab = (tab: any, depth: number = 0): string => {\n const indent = ' '.repeat(depth);\n let result = `${indent}- Tab: \"${tab.tabProperties?.title || 'Untitled'}\" (ID: ${tab.tabProperties?.tabId})`;\n\n if (a.includeContent && tab.documentTab?.body?.content) {\n let charCount = 0;\n for (const element of tab.documentTab.body.content) {\n if (element.paragraph?.elements) {\n for (const elem of element.paragraph.elements) {\n if (elem.textRun?.content) {\n charCount += elem.textRun.content.length;\n }\n }\n }\n }\n result += ` (${charCount} characters)`;\n }\n\n if (tab.childTabs) {\n for (const childTab of tab.childTabs) {\n result += '\\n' + processTab(childTab, depth + 1);\n }\n }\n\n return result;\n };\n\n let tabList = `Document \"${doc.title}\" tabs:\\n`;\n for (const tab of tabs) {\n tabList += processTab(tab) + '\\n';\n }\n\n return {\n content: [{ type: \"text\", text: tabList }],\n isError: false\n };\n }\n\n // =========================================================================\n // TEXT & PARAGRAPH STYLE\n // =========================================================================\n\n case \"applyTextStyle\":\n case \"formatGoogleDocText\": {\n const validation = ApplyTextStyleSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n let startIndex: number;\n let endIndex: number;\n\n // Determine target range (flat parameters)\n if (a.startIndex !== undefined && a.endIndex !== undefined) {\n startIndex = a.startIndex;\n endIndex = a.endIndex;\n } else if (a.textToFind !== undefined) {\n const range = await findTextRange(\n ctx,\n a.documentId,\n a.textToFind,\n a.matchInstance || 1\n );\n if (!range) {\n return errorResponse(`Text \"${a.textToFind}\" not found in document`);\n }\n startIndex = range.startIndex;\n endIndex = range.endIndex;\n } else {\n return errorResponse(\"Must provide either startIndex+endIndex or textToFind\");\n }\n\n // Build style object from flat parameters\n const style = {\n bold: a.bold,\n italic: a.italic,\n underline: a.underline,\n strikethrough: a.strikethrough,\n fontSize: a.fontSize,\n fontFamily: a.fontFamily,\n foregroundColor: a.foregroundColor,\n backgroundColor: a.backgroundColor,\n linkUrl: a.linkUrl\n };\n\n // Build the update request\n const styleResult = buildUpdateTextStyleRequest(startIndex, endIndex, style);\n if (!styleResult) {\n return errorResponse(\"No valid style options provided\");\n }\n\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n await docs.documents.batchUpdate({\n documentId: a.documentId,\n requestBody: {\n requests: [styleResult.request]\n }\n });\n\n return {\n content: [{ type: \"text\", text: `Successfully applied text style to range ${startIndex}-${endIndex}` }],\n isError: false\n };\n }\n\n case \"applyParagraphStyle\":\n case \"formatGoogleDocParagraph\": {\n const validation = ApplyParagraphStyleSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n let startIndex: number;\n let endIndex: number;\n\n // Determine target range (flat parameters)\n if (a.startIndex !== undefined && a.endIndex !== undefined) {\n startIndex = a.startIndex;\n endIndex = a.endIndex;\n } else if (a.textToFind !== undefined) {\n const range = await findTextRange(\n ctx,\n a.documentId,\n a.textToFind,\n a.matchInstance || 1\n );\n if (!range) {\n return errorResponse(`Text \"${a.textToFind}\" not found in document`);\n }\n // For paragraph style, get the full paragraph range\n const paraRange = await getParagraphRange(ctx, a.documentId, range.startIndex);\n if (!paraRange) {\n return errorResponse(\"Could not determine paragraph boundaries\");\n }\n startIndex = paraRange.startIndex;\n endIndex = paraRange.endIndex;\n } else if (a.indexWithinParagraph !== undefined) {\n const paraRange = await getParagraphRange(ctx, a.documentId, a.indexWithinParagraph);\n if (!paraRange) {\n return errorResponse(\"Could not determine paragraph boundaries\");\n }\n startIndex = paraRange.startIndex;\n endIndex = paraRange.endIndex;\n } else {\n return errorResponse(\"Must provide either startIndex+endIndex, textToFind, or indexWithinParagraph\");\n }\n\n // Build style object from flat parameters\n const style = {\n alignment: a.alignment,\n indentStart: a.indentStart,\n indentEnd: a.indentEnd,\n spaceAbove: a.spaceAbove,\n spaceBelow: a.spaceBelow,\n namedStyleType: a.namedStyleType,\n keepWithNext: a.keepWithNext\n };\n\n // Build the update request\n const styleResult = buildUpdateParagraphStyleRequest(startIndex, endIndex, style);\n if (!styleResult) {\n return errorResponse(\"No valid style options provided\");\n }\n\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n await docs.documents.batchUpdate({\n documentId: a.documentId,\n requestBody: {\n requests: [styleResult.request]\n }\n });\n\n return {\n content: [{ type: \"text\", text: `Successfully applied paragraph style to range ${startIndex}-${endIndex}` }],\n isError: false\n };\n }\n\n\n case \"createParagraphBullets\": {\n const validation = CreateParagraphBulletsSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n let startIndex: number;\n let endIndex: number;\n\n if (a.startIndex !== undefined && a.endIndex !== undefined) {\n startIndex = a.startIndex;\n endIndex = a.endIndex;\n } else if (a.textToFind !== undefined) {\n const range = await findTextRange(\n ctx,\n a.documentId,\n a.textToFind,\n a.matchInstance || 1\n );\n if (!range) {\n return errorResponse(`Text \"${a.textToFind}\" not found in document`);\n }\n startIndex = range.startIndex;\n endIndex = range.endIndex;\n } else {\n return errorResponse(\"Must provide either startIndex+endIndex or textToFind\");\n }\n\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n\n if (a.bulletPreset === 'NONE') {\n await docs.documents.batchUpdate({\n documentId: a.documentId,\n requestBody: {\n requests: [{\n deleteParagraphBullets: {\n range: { startIndex, endIndex }\n }\n }]\n }\n });\n return {\n content: [{ type: \"text\", text: `Removed bullets from range ${startIndex}-${endIndex}` }],\n isError: false\n };\n }\n\n await docs.documents.batchUpdate({\n documentId: a.documentId,\n requestBody: {\n requests: [{\n createParagraphBullets: {\n range: { startIndex, endIndex },\n bulletPreset: a.bulletPreset\n }\n }]\n }\n });\n\n return {\n content: [{ type: \"text\", text: `Applied ${a.bulletPreset} bullets to range ${startIndex}-${endIndex}` }],\n isError: false\n };\n }\n\n case \"findAndReplaceInDoc\": {\n const validation = FindAndReplaceInDocSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n\n if (a.dryRun) {\n const doc = await docs.documents.get({ documentId: a.documentId });\n let text = '';\n const content = doc.data.body?.content || [];\n for (const el of content) {\n if (el.paragraph?.elements) {\n for (const elem of el.paragraph.elements) {\n if (elem.textRun?.content) text += elem.textRun.content;\n }\n }\n }\n const escaped = a.findText.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const flags = a.matchCase ? 'g' : 'gi';\n const matches = text.match(new RegExp(escaped, flags));\n const count = matches ? matches.length : 0;\n return {\n content: [{ type: 'text', text: `Dry run (paragraph text only, approximate): found ${count} occurrence(s) of \"${a.findText}\". Note: actual replacement covers the full document including tables, headers, and footers.` }],\n isError: false,\n };\n }\n\n const response = await docs.documents.batchUpdate({\n documentId: a.documentId,\n requestBody: {\n requests: [\n {\n replaceAllText: {\n containsText: {\n text: a.findText,\n matchCase: a.matchCase,\n },\n replaceText: a.replaceText,\n },\n },\n ],\n },\n });\n\n const occurrences = response.data.replies?.[0]?.replaceAllText?.occurrencesChanged ?? 0;\n return {\n content: [{ type: 'text', text: `Replaced ${occurrences} occurrence(s) of \"${a.findText}\".` }],\n isError: false,\n };\n }\n\n // =========================================================================\n // COMMENT TOOLS (use Drive API v3)\n // =========================================================================\n\n case \"listComments\": {\n const validation = ListCommentsSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const response = await ctx.getDrive().comments.list({\n fileId: a.documentId,\n fields: 'comments(id,content,quotedFileContent,author,createdTime,resolved,replies(id,content,author,createdTime)),nextPageToken',\n pageSize: a.pageSize || 100,\n pageToken: a.pageToken,\n includeDeleted: a.includeDeleted || false,\n });\n\n const comments = response.data.comments || [];\n const nextPageToken = response.data.nextPageToken;\n\n if (comments.length === 0) {\n return {\n content: [{ type: \"text\", text: \"No comments found in this document.\" }],\n isError: false\n };\n }\n\n // \u2500\u2500 Comment context extraction (two-tiered) \u2500\u2500\n // Tier 1 (fast): Read doc via Docs API, find each comment's quotedFileContent\n // in the body text. If there's exactly one match, extract surrounding context.\n // Tier 2 (fallback): For ambiguous or failed Tier 1 comments, export as DOCX\n // and parse commentRangeStart/End XML markers. Match by (author, createdTime).\n const contextMap = new Map<string, CommentContext>();\n let flatText = '';\n let offsetMap: number[] = [];\n\n // \u2500\u2500 Tier 1: Docs API text matching \u2500\u2500\n // Check MIME type upfront \u2014 only Google Docs support the Docs API\n let needsDocxFallback = false;\n let isGoogleDoc = false;\n try {\n const fileInfo = await ctx.getDrive().files.get({\n fileId: a.documentId,\n fields: 'mimeType',\n supportsAllDrives: true,\n });\n isGoogleDoc = fileInfo.data.mimeType === 'application/vnd.google-apps.document';\n } catch (err) {\n ctx.log('Failed to check file MIME type:', err);\n }\n\n if (isGoogleDoc) {\n try {\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n const docResponse = await docs.documents.get({\n documentId: a.documentId,\n includeTabsContent: true,\n });\n\n const result = buildFlatTextFromDoc(docResponse.data);\n flatText = result.flatText;\n offsetMap = result.offsetMap;\n\n // Get surrounding context for a match at a flatText position\n function getContext(matchStart: number, matchLen: number): { before: string; after: string } {\n const matchText = flatText.substring(matchStart, matchStart + matchLen);\n const beforeStart = Math.max(0, matchStart - 120);\n let before = flatText.substring(beforeStart, matchStart).trim();\n if (beforeStart > 0) before = '...' + before;\n before = before + matchText;\n const afterEnd = Math.min(flatText.length, matchStart + matchLen + 120);\n let after = flatText.substring(matchStart + matchLen, afterEnd).trim();\n if (afterEnd < flatText.length) after = after + '...';\n after = matchText + after;\n return { before, after };\n }\n\n // For each comment, find all occurrences of its quotedFileContent in the doc\n const ambiguousComments: any[] = [];\n for (const comment of comments) {\n const quoted = comment.quotedFileContent?.value;\n if (!quoted) continue;\n\n const positions: number[] = [];\n let searchFrom = 0;\n while (true) {\n const idx = flatText.indexOf(quoted, searchFrom);\n if (idx === -1) break;\n positions.push(idx);\n searchFrom = idx + 1;\n }\n\n if (positions.length === 1) {\n const surrounding = getContext(positions[0], quoted.length);\n const entry: CommentContext = {\n contextBefore: surrounding.before,\n contextAfter: surrounding.after,\n };\n // Store Docs API character offsets with bounds check\n const endIdx = positions[0] + quoted.length - 1;\n if (endIdx < offsetMap.length) {\n entry.startIndex = offsetMap[positions[0]];\n entry.endIndex = offsetMap[endIdx] + 1;\n }\n if (comment.id) contextMap.set(comment.id, entry);\n } else if (positions.length > 1) {\n // Ambiguous \u2014 need DOCX fallback to disambiguate\n ambiguousComments.push(comment);\n }\n // positions.length === 0: quoted text not found (e.g., doc was edited since comment)\n }\n\n needsDocxFallback = ambiguousComments.length > 0;\n } catch (err) {\n ctx.log('Tier 1 context extraction failed:', err);\n needsDocxFallback = true;\n }\n }\n\n // \u2500\u2500 Tier 2: DOCX export fallback for ambiguous comments \u2500\u2500\n if (needsDocxFallback) {\n const unresolved = comments.filter((c: any) => !contextMap.has(c.id) && !c.resolved);\n\n if (unresolved.length > 0) {\n try {\n const docxResponse = await ctx.getDrive().files.export({\n fileId: a.documentId,\n mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n }, { responseType: 'arraybuffer' });\n\n const docxResult = await resolveContextFromDocx(docxResponse.data as ArrayBuffer);\n if (docxResult) {\n matchDocxToDriveComments(comments, docxResult, contextMap, flatText, offsetMap);\n }\n } catch (err) {\n ctx.log('Tier 2 DOCX context extraction failed:', err);\n }\n }\n }\n\n // \u2500\u2500 Format comments for display \u2500\u2500\n const formattedComments = comments.map((comment: any, index: number) => {\n const status = comment.resolved ? ' [RESOLVED]' : '';\n const author = comment.author?.displayName || 'Unknown';\n const date = comment.createdTime ? new Date(comment.createdTime).toLocaleDateString() : 'Unknown date';\n const quotedText = comment.quotedFileContent?.value;\n const commentCtx = contextMap.get(comment.id);\n\n let positionInfo = '';\n const indexStr = commentCtx?.startIndex != null\n ? ` [chars ${commentCtx.startIndex}-${commentCtx.endIndex}]` : '';\n\n if (quotedText) {\n const snippet = quotedText.length > 100 ? quotedText.substring(0, 100) + '...' : quotedText;\n positionInfo = `\\n Anchored to: \"${snippet}\"${indexStr}`;\n }\n if (commentCtx) {\n if (commentCtx.contextBefore) positionInfo += `\\n Context before: \"${commentCtx.contextBefore}\"`;\n if (commentCtx.contextAfter) positionInfo += `\\n Context after: \"${commentCtx.contextAfter}\"`;\n }\n\n let result = `${index + 1}. ${author} (${date})${status}${positionInfo}\\n Comment: ${comment.content}`;\n\n if (comment.replies && comment.replies.length > 0) {\n for (const reply of comment.replies) {\n const replyAuthor = reply.author?.displayName || 'Unknown';\n const replyDate = reply.createdTime ? new Date(reply.createdTime).toLocaleDateString() : 'Unknown date';\n const replyContent = reply.content || '(empty)';\n result += `\\n \u2514\u2500 ${replyAuthor} (${replyDate}): ${replyContent}`;\n }\n }\n\n result += `\\n Comment ID: ${comment.id}`;\n return result;\n }).join('\\n\\n');\n\n let text = `Found ${comments.length} comment${comments.length === 1 ? '' : 's'}:\\n\\n${formattedComments}`;\n if (nextPageToken) {\n text += `\\n\\nMore comments available. Use pageToken: \"${nextPageToken}\" to fetch the next page.`;\n }\n\n return {\n content: [{ type: \"text\", text }],\n isError: false\n };\n }\n\n case \"getComment\": {\n const validation = GetCommentSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const response = await ctx.getDrive().comments.get({\n fileId: a.documentId,\n commentId: a.commentId,\n fields: 'id,content,quotedFileContent,author,createdTime,resolved,replies(id,content,author,createdTime)'\n });\n\n const comment = response.data;\n const author = comment.author?.displayName || 'Unknown';\n const date = comment.createdTime ? new Date(comment.createdTime).toLocaleDateString() : 'Unknown date';\n const status = comment.resolved ? ' [RESOLVED]' : '';\n const quotedText = comment.quotedFileContent?.value || 'No quoted text';\n const anchor = quotedText !== 'No quoted text' ? `\\nAnchored to: \"${quotedText}\"` : '';\n\n let result = `${author} (${date})${status}${anchor}\\n${comment.content}`;\n\n if (comment.replies && comment.replies.length > 0) {\n result += '\\n\\nReplies:';\n comment.replies.forEach((reply: any, index: number) => {\n const replyAuthor = reply.author?.displayName || 'Unknown';\n const replyDate = reply.createdTime ? new Date(reply.createdTime).toLocaleDateString() : 'Unknown date';\n result += `\\n${index + 1}. ${replyAuthor} (${replyDate})\\n ${reply.content}`;\n });\n }\n\n return {\n content: [{ type: \"text\", text: result }],\n isError: false\n };\n }\n\n case \"addComment\": {\n const validation = AddCommentSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n if (a.endIndex <= a.startIndex) {\n return errorResponse(\"endIndex must be greater than startIndex\");\n }\n\n // Get the document to extract quoted text\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n const doc = await docs.documents.get({ documentId: a.documentId });\n\n // Extract quoted text from the range\n let quotedText = '';\n const content = doc.data.body?.content || [];\n for (const element of content) {\n if (element.paragraph?.elements) {\n for (const textElement of element.paragraph.elements) {\n if (textElement.textRun) {\n const elementStart = textElement.startIndex || 0;\n const elementEnd = textElement.endIndex || 0;\n\n if (elementEnd > a.startIndex && elementStart < a.endIndex) {\n const text = textElement.textRun.content || '';\n const startOffset = Math.max(0, a.startIndex - elementStart);\n const endOffset = Math.min(text.length, a.endIndex - elementStart);\n quotedText += text.substring(startOffset, endOffset);\n }\n }\n }\n }\n }\n\n const response = await ctx.getDrive().comments.create({\n fileId: a.documentId,\n fields: 'id,content,quotedFileContent,author,createdTime',\n requestBody: {\n content: a.commentText,\n quotedFileContent: {\n value: quotedText,\n mimeType: 'text/html'\n },\n // Reverse-engineered anchor format for positioning comments.\n // Not part of the public Drive API -- may break if Google changes internals.\n // See: https://stackoverflow.com/questions/51789168\n anchor: JSON.stringify({\n r: a.documentId,\n a: [{\n txt: {\n o: a.startIndex - 1, // Drive API uses 0-based indexing\n l: a.endIndex - a.startIndex,\n ml: a.endIndex - a.startIndex\n }\n }]\n })\n }\n });\n\n return {\n content: [{ type: \"text\", text: `Comment added successfully. Comment ID: ${response.data.id}` }],\n isError: false\n };\n }\n\n case \"replyToComment\": {\n const validation = ReplyToCommentSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const response = await ctx.getDrive().replies.create({\n fileId: a.documentId,\n commentId: a.commentId,\n fields: 'id,content,author,createdTime',\n requestBody: {\n content: a.replyText,\n ...(a.resolve && { action: \"resolve\" })\n }\n });\n\n const resolveNote = a.resolve ? ' Comment thread resolved.' : '';\n return {\n content: [{ type: \"text\", text: `Reply added successfully. Reply ID: ${response.data.id}${resolveNote}` }],\n isError: false\n };\n }\n\n case \"deleteComment\": {\n const validation = DeleteCommentSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n await ctx.getDrive().comments.delete({\n fileId: a.documentId,\n commentId: a.commentId\n });\n\n return {\n content: [{ type: \"text\", text: `Comment ${a.commentId} has been deleted.` }],\n isError: false\n };\n }\n\n // =========================================================================\n // TABLE & MEDIA TOOLS\n // =========================================================================\n\n case \"insertTable\": {\n const validation = InsertTableSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const request_body = {\n insertTable: {\n location: { index: a.index },\n rows: a.rows,\n columns: a.columns\n }\n };\n\n await executeBatchUpdate(ctx, a.documentId, [request_body]);\n\n return {\n content: [{ type: \"text\", text: `Successfully inserted ${a.rows}x${a.columns} table at index ${a.index}` }],\n isError: false\n };\n }\n\n case \"editTableCell\": {\n const validation = EditTableCellSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n // Get the document to find the table structure\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n\n const docRes = await docs.documents.get({\n documentId: a.documentId,\n fields: 'body(content)'\n });\n\n // Find the table at the specified start index\n let table: any = null;\n const findTable = (content: any[]) => {\n for (const elem of content) {\n if (elem.table && elem.startIndex === a.tableStartIndex) {\n table = elem.table;\n return;\n }\n }\n };\n\n if (docRes.data.body?.content) {\n findTable(docRes.data.body.content);\n }\n\n if (!table) {\n return errorResponse(`No table found at index ${a.tableStartIndex}`);\n }\n\n // Get the cell\n const row = table.tableRows?.[a.rowIndex];\n if (!row) {\n return errorResponse(`Row ${a.rowIndex} not found in table`);\n }\n\n const cell = row.tableCells?.[a.columnIndex];\n if (!cell) {\n return errorResponse(`Column ${a.columnIndex} not found in row ${a.rowIndex}`);\n }\n\n // Get cell content range\n const cellStartIndex = cell.startIndex;\n const cellEndIndex = cell.endIndex;\n\n const requests: any[] = [];\n\n // If textContent is provided, delete existing content and insert new\n if (a.textContent !== undefined) {\n // Delete existing content (keeping the paragraph structure)\n const cellContentStart = cellStartIndex + 1; // Skip the cell start marker\n const cellContentEnd = cellEndIndex - 1; // Before cell end marker\n\n if (cellContentEnd > cellContentStart) {\n requests.push({\n deleteContentRange: {\n range: { startIndex: cellContentStart, endIndex: cellContentEnd }\n }\n });\n }\n\n // Insert new text\n if (a.textContent.length > 0) {\n requests.push({\n insertText: {\n location: { index: cellContentStart },\n text: a.textContent\n }\n });\n }\n }\n\n // Apply text styling if any style options provided\n if (a.bold !== undefined || a.italic !== undefined || a.fontSize !== undefined) {\n const textStyle: any = {};\n const fields: string[] = [];\n\n if (a.bold !== undefined) { textStyle.bold = a.bold; fields.push('bold'); }\n if (a.italic !== undefined) { textStyle.italic = a.italic; fields.push('italic'); }\n if (a.fontSize !== undefined) { textStyle.fontSize = { magnitude: a.fontSize, unit: 'PT' }; fields.push('fontSize'); }\n\n if (fields.length > 0) {\n // Apply to the cell content range\n const styleStart = cellStartIndex + 1;\n const styleEnd = a.textContent !== undefined\n ? styleStart + a.textContent.length\n : cellEndIndex - 1;\n\n requests.push({\n updateTextStyle: {\n range: { startIndex: styleStart, endIndex: styleEnd },\n textStyle,\n fields: fields.join(',')\n }\n });\n }\n }\n\n // Apply paragraph alignment if provided\n if (a.alignment !== undefined) {\n requests.push({\n updateParagraphStyle: {\n range: { startIndex: cellStartIndex + 1, endIndex: cellEndIndex - 1 },\n paragraphStyle: { alignment: a.alignment },\n fields: 'alignment'\n }\n });\n }\n\n if (requests.length === 0) {\n return errorResponse(\"No changes specified for the table cell\");\n }\n\n await executeBatchUpdate(ctx, a.documentId, requests);\n\n return {\n content: [{ type: \"text\", text: `Successfully edited cell at row ${a.rowIndex}, column ${a.columnIndex}` }],\n isError: false\n };\n }\n\n case \"insertImageFromUrl\": {\n const validation = InsertImageFromUrlSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n await insertInlineImageHelper(ctx, a.documentId, a.imageUrl, a.index, a.width, a.height);\n\n return {\n content: [{ type: \"text\", text: `Successfully inserted image from URL at index ${a.index}` }],\n isError: false\n };\n }\n\n case \"insertLocalImage\": {\n const validation = InsertLocalImageSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n // Get the document's parent folder if uploadToSameFolder is true\n let parentFolderId: string | undefined;\n if (a.uploadToSameFolder !== false) {\n const fileInfo = await ctx.getDrive().files.get({\n fileId: a.documentId,\n fields: 'parents',\n supportsAllDrives: true\n });\n parentFolderId = fileInfo.data.parents?.[0];\n }\n\n // Upload the image to Drive\n const { webContentLink: imageUrl } = await uploadImageToDrive(ctx, a.localImagePath, {\n parentFolderId,\n makePublic: a.makePublic,\n });\n\n // Insert the image into the document\n await insertInlineImageHelper(ctx, a.documentId, imageUrl, a.index, a.width, a.height);\n\n return {\n content: [{ type: \"text\", text: `Successfully uploaded and inserted local image at index ${a.index}\\nImage URL: ${imageUrl}` }],\n isError: false\n };\n }\n\n // =========================================================================\n // GOOGLE DOCS DISCOVERY & MANAGEMENT TOOLS\n // =========================================================================\n\n case \"listGoogleDocs\": {\n const validation = ListGoogleDocsSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n // Build the query string for Google Drive API\n let queryString = \"mimeType='application/vnd.google-apps.document' and trashed=false\";\n if (a.query) {\n const escapedQuery = escapeDriveQuery(a.query);\n queryString += ` and (name contains '${escapedQuery}' or fullText contains '${escapedQuery}')`;\n }\n\n const response = await ctx.getDrive().files.list({\n q: queryString,\n pageSize: a.maxResults,\n orderBy: a.orderBy === 'name' ? 'name' : a.orderBy,\n fields: 'files(id,name,modifiedTime,createdTime,size,webViewLink,owners(displayName,emailAddress))',\n supportsAllDrives: true,\n includeItemsFromAllDrives: true\n });\n\n const files = response.data.files || [];\n\n if (files.length === 0) {\n return { content: [{ type: \"text\", text: \"No Google Docs found matching your criteria.\" }], isError: false };\n }\n\n let result = `Found ${files.length} Google Document(s):\\n\\n`;\n for (let i = 0; i < files.length; i++) {\n const file = files[i];\n const modifiedDate = file.modifiedTime ? new Date(file.modifiedTime).toLocaleDateString() : 'Unknown';\n const owner = file.owners?.[0]?.displayName || 'Unknown';\n result += `${i + 1}. **${file.name}**\\n`;\n result += ` ID: ${file.id}\\n`;\n result += ` Modified: ${modifiedDate}\\n`;\n result += ` Owner: ${owner}\\n`;\n result += ` Link: ${file.webViewLink}\\n\\n`;\n }\n\n return { content: [{ type: \"text\", text: result }], isError: false };\n }\n\n case \"getDocumentInfo\": {\n const validation = GetDocumentInfoSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const response = await ctx.getDrive().files.get({\n fileId: a.documentId,\n fields: 'id,name,description,mimeType,size,createdTime,modifiedTime,webViewLink,owners(displayName,emailAddress),lastModifyingUser(displayName,emailAddress),shared,parents,version',\n });\n\n const file = response.data;\n\n if (!file) {\n return errorResponse(`Document with ID ${a.documentId} not found.`);\n }\n\n const createdDate = file.createdTime ? new Date(file.createdTime).toLocaleString() : 'Unknown';\n const modifiedDate = file.modifiedTime ? new Date(file.modifiedTime).toLocaleString() : 'Unknown';\n const owner = file.owners?.[0];\n const lastModifier = (file as any).lastModifyingUser;\n\n let result = `**Document Information:**\\n\\n`;\n result += `**Name:** ${file.name}\\n`;\n result += `**ID:** ${file.id}\\n`;\n result += `**Type:** Google Document\\n`;\n result += `**Created:** ${createdDate}\\n`;\n result += `**Last Modified:** ${modifiedDate}\\n`;\n\n if (owner) {\n result += `**Owner:** ${owner.displayName} (${owner.emailAddress})\\n`;\n }\n\n if (lastModifier) {\n result += `**Last Modified By:** ${lastModifier.displayName} (${lastModifier.emailAddress})\\n`;\n }\n\n if (file.description) {\n result += `**Description:** ${file.description}\\n`;\n }\n\n result += `**Shared:** ${file.shared ? 'Yes' : 'No'}\\n`;\n result += `**Version:** ${file.version || 'Unknown'}\\n`;\n result += `**View Link:** ${file.webViewLink}\\n`;\n\n return { content: [{ type: \"text\", text: result }], isError: false };\n }\n\n case \"addDocumentTab\": {\n const validation = AddDocumentTabSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const a = validation.data;\n\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n await docs.documents.batchUpdate({\n documentId: a.documentId,\n // addDocumentTab is not yet in the googleapis TypeScript types \u2014 cast required\n requestBody: { requests: [{ addDocumentTab: { tabProperties: { title: a.title } } } as any] }\n });\n\n return { content: [{ type: 'text', text: `Requested creation of tab \"${a.title}\" in document ${a.documentId}.` }], isError: false };\n }\n\n case \"renameDocumentTab\": {\n const validation = RenameDocumentTabSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const a = validation.data;\n\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n await docs.documents.batchUpdate({\n documentId: a.documentId,\n // updateDocumentTabProperties is not yet in the googleapis TypeScript types \u2014 cast required\n requestBody: { requests: [{ updateDocumentTabProperties: { tabId: a.tabId, tabProperties: { title: a.title }, fields: 'title' } } as any] }\n });\n\n return { content: [{ type: 'text', text: `Renamed tab ${a.tabId} to \"${a.title}\".` }], isError: false };\n }\n\n case \"insertSmartChip\": {\n const validation = InsertSmartChipSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const a = validation.data;\n\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n await docs.documents.batchUpdate({\n documentId: a.documentId,\n requestBody: {\n requests: [{\n insertPerson: {\n personProperties: { email: a.personEmail },\n location: { index: a.index },\n },\n // insertPerson is not yet in the googleapis TypeScript types \u2014 cast required\n } as any],\n },\n });\n\n return { content: [{ type: 'text', text: `Inserted person smart chip for ${a.personEmail} at index ${a.index}.` }], isError: false };\n }\n\n case \"readSmartChips\": {\n const validation = ReadSmartChipsSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const a = validation.data;\n\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n const doc = await docs.documents.get({ documentId: a.documentId });\n const body = (doc.data as any).body?.content || [];\n const hits: string[] = [];\n for (const block of body) {\n for (const el of block?.paragraph?.elements || []) {\n if (el?.richLink) hits.push(`richLink: ${el.richLink.richLinkProperties?.uri || 'unknown'}`);\n if (el?.person) hits.push(`person: ${el.person.personProperties?.email || 'unknown'}`);\n }\n }\n // Date chips appear as richLink elements in the Docs API model \u2014 already covered above.\n return { content: [{ type: 'text', text: hits.length ? hits.join('\\n') : 'No smart chips detected (note: only the default tab is scanned).' }], isError: false };\n }\n\n case \"createFootnote\": {\n const validation = CreateFootnoteSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const a = validation.data;\n\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n\n // Build the createFootnote request\n const createFootnoteReq: { location?: { index: number }; endOfSegmentLocation?: { segmentId: string } } = {};\n if (a.index !== undefined) {\n createFootnoteReq.location = { index: a.index };\n } else {\n createFootnoteReq.endOfSegmentLocation = { segmentId: \"\" };\n }\n\n const res = await docs.documents.batchUpdate({\n documentId: a.documentId,\n requestBody: {\n requests: [{ createFootnote: createFootnoteReq }],\n },\n });\n\n const footnoteId = res.data.replies?.[0]?.createFootnote?.footnoteId;\n if (!footnoteId) {\n return errorResponse(\"Failed to create footnote \u2014 no footnoteId in response.\");\n }\n\n const locationDesc = a.index !== undefined ? `at index ${a.index}` : 'at end of document';\n\n // Optionally insert text content into the footnote body\n if (a.content) {\n try {\n await docs.documents.batchUpdate({\n documentId: a.documentId,\n requestBody: {\n requests: [{\n insertText: {\n location: { segmentId: footnoteId, index: 0 },\n text: a.content,\n },\n }],\n },\n });\n } catch (err: any) {\n return { content: [{ type: 'text', text: `Created footnote ${footnoteId} ${locationDesc}, but failed to insert content: ${err.message}` }], isError: true };\n }\n }\n\n return { content: [{ type: 'text', text: `Created footnote ${footnoteId} ${locationDesc}.${a.content ? ' Content inserted.' : ''}` }], isError: false };\n }\n\n default:\n return null;\n }\n}\n", "import { existsSync, createReadStream } from 'fs';\nimport { basename, extname } from 'path';\nimport type { ToolContext } from '../types.js';\n\nconst MIME_BY_EXT: { [ext: string]: string } = {\n '.jpg': 'image/jpeg',\n '.jpeg': 'image/jpeg',\n '.png': 'image/png',\n '.gif': 'image/gif',\n '.bmp': 'image/bmp',\n '.webp': 'image/webp',\n '.svg': 'image/svg+xml',\n};\n\nexport interface UploadedImage {\n fileId: string;\n webContentLink: string;\n}\n\nexport async function uploadImageToDrive(\n ctx: ToolContext,\n localFilePath: string,\n options: { parentFolderId?: string; makePublic?: boolean } = {},\n): Promise<UploadedImage> {\n const { parentFolderId, makePublic = false } = options;\n\n if (!existsSync(localFilePath)) {\n throw new Error(`Image file not found: ${localFilePath}`);\n }\n\n const fileName = basename(localFilePath);\n const ext = extname(localFilePath).toLowerCase();\n const mimeType = MIME_BY_EXT[ext] || 'application/octet-stream';\n\n const requestBody: { name: string; mimeType: string; parents?: string[] } = {\n name: fileName,\n mimeType,\n };\n if (parentFolderId) requestBody.parents = [parentFolderId];\n\n const drive = ctx.getDrive();\n\n const uploadResponse = await drive.files.create({\n requestBody,\n media: { mimeType, body: createReadStream(localFilePath) },\n fields: 'id,webViewLink,webContentLink',\n supportsAllDrives: true,\n });\n\n const fileId = uploadResponse.data.id;\n if (!fileId) throw new Error('Failed to upload image to Drive - no file ID returned');\n\n if (makePublic) {\n await drive.permissions.create({\n fileId,\n requestBody: { role: 'reader', type: 'anyone' },\n });\n }\n\n const fileInfo = await drive.files.get({\n fileId,\n fields: 'webContentLink',\n supportsAllDrives: true,\n });\n\n const webContentLink = fileInfo.data.webContentLink;\n if (!webContentLink) throw new Error('Failed to get web content link for uploaded image');\n\n return { fileId, webContentLink };\n}\n\nexport async function deleteDriveFile(ctx: ToolContext, fileId: string): Promise<void> {\n await ctx.getDrive().files.delete({ fileId, supportsAllDrives: true });\n}\n", "import { z } from 'zod';\nimport type { ToolDefinition, ToolResult, ToolContext } from '../types.js';\nimport { errorResponse } from '../types.js';\nimport { parseA1Range, convertA1ToGridRange, escapeDriveQuery, type GridRange } from '../utils.js';\n\n// ---------------------------------------------------------------------------\n// Zod Schemas\n// ---------------------------------------------------------------------------\n\nconst CreateGoogleSheetSchema = z.object({\n name: z.string().min(1, \"Sheet name is required\"),\n data: z.array(z.array(z.string())),\n parentFolderId: z.string().optional(),\n valueInputOption: z.enum([\"RAW\", \"USER_ENTERED\"]).optional()\n});\n\nconst UpdateGoogleSheetSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n range: z.string().min(1, \"Range is required\"),\n data: z.array(z.array(z.string())),\n valueInputOption: z.enum([\"RAW\", \"USER_ENTERED\"]).optional()\n});\n\nconst GetGoogleSheetContentSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n range: z.string().min(1, \"Range is required\")\n});\n\nconst FormatGoogleSheetCellsSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n range: z.string().min(1, \"Range is required\"),\n backgroundColor: z.object({\n red: z.number().min(0).max(1).optional(),\n green: z.number().min(0).max(1).optional(),\n blue: z.number().min(0).max(1).optional()\n }).optional(),\n horizontalAlignment: z.enum([\"LEFT\", \"CENTER\", \"RIGHT\"]).optional(),\n verticalAlignment: z.enum([\"TOP\", \"MIDDLE\", \"BOTTOM\"]).optional(),\n wrapStrategy: z.enum([\"OVERFLOW_CELL\", \"CLIP\", \"WRAP\"]).optional()\n});\n\nconst FormatGoogleSheetTextSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n range: z.string().min(1, \"Range is required\"),\n bold: z.boolean().optional(),\n italic: z.boolean().optional(),\n strikethrough: z.boolean().optional(),\n underline: z.boolean().optional(),\n fontSize: z.number().min(1).optional(),\n fontFamily: z.string().optional(),\n foregroundColor: z.object({\n red: z.number().min(0).max(1).optional(),\n green: z.number().min(0).max(1).optional(),\n blue: z.number().min(0).max(1).optional()\n }).optional()\n});\n\nconst FormatGoogleSheetNumbersSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n range: z.string().min(1, \"Range is required\"),\n pattern: z.string().min(1, \"Pattern is required\"),\n type: z.enum([\"NUMBER\", \"CURRENCY\", \"PERCENT\", \"DATE\", \"TIME\", \"DATE_TIME\", \"SCIENTIFIC\"]).optional()\n});\n\nconst SetGoogleSheetBordersSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n range: z.string().min(1, \"Range is required\"),\n style: z.enum([\"SOLID\", \"DASHED\", \"DOTTED\", \"DOUBLE\"]),\n width: z.number().min(1).max(3).optional(),\n color: z.object({\n red: z.number().min(0).max(1).optional(),\n green: z.number().min(0).max(1).optional(),\n blue: z.number().min(0).max(1).optional()\n }).optional(),\n top: z.boolean().optional(),\n bottom: z.boolean().optional(),\n left: z.boolean().optional(),\n right: z.boolean().optional(),\n innerHorizontal: z.boolean().optional(),\n innerVertical: z.boolean().optional()\n});\n\nconst MergeGoogleSheetCellsSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n range: z.string().min(1, \"Range is required\"),\n mergeType: z.enum([\"MERGE_ALL\", \"MERGE_COLUMNS\", \"MERGE_ROWS\"])\n});\n\nconst AddGoogleSheetConditionalFormatSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n range: z.string().min(1, \"Range is required\"),\n condition: z.object({\n type: z.enum([\"NUMBER_GREATER\", \"NUMBER_LESS\", \"TEXT_CONTAINS\", \"TEXT_STARTS_WITH\", \"TEXT_ENDS_WITH\", \"CUSTOM_FORMULA\"]),\n value: z.string()\n }),\n format: z.object({\n backgroundColor: z.object({\n red: z.number().min(0).max(1).optional(),\n green: z.number().min(0).max(1).optional(),\n blue: z.number().min(0).max(1).optional()\n }).optional(),\n textFormat: z.object({\n bold: z.boolean().optional(),\n foregroundColor: z.object({\n red: z.number().min(0).max(1).optional(),\n green: z.number().min(0).max(1).optional(),\n blue: z.number().min(0).max(1).optional()\n }).optional()\n }).optional()\n })\n});\n\nconst GetSpreadsheetInfoSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\")\n});\n\nconst AppendSpreadsheetRowsSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n range: z.string().min(1, \"Range is required\"),\n values: z.array(z.array(z.any())),\n valueInputOption: z.enum([\"RAW\", \"USER_ENTERED\"]).optional().default(\"USER_ENTERED\")\n});\n\nconst AddSpreadsheetSheetSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n sheetTitle: z.string().min(1, \"Sheet title is required\")\n});\n\nconst AddSheetSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n title: z.string().min(1, \"Sheet title is required\")\n});\n\nconst ListSheetsSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\")\n});\n\nconst RenameSheetSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n sheetId: z.number().int(),\n newTitle: z.string().min(1, \"New title is required\")\n});\n\nconst DeleteSheetSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n sheetId: z.number().int()\n});\n\nconst AddDataValidationSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n range: z.string().min(1, \"Range is required\"),\n conditionType: z.enum([\"ONE_OF_LIST\", \"NUMBER_GREATER\", \"NUMBER_LESS\", \"TEXT_CONTAINS\"]),\n values: z.array(z.string()).min(1, \"At least one value is required\"),\n strict: z.boolean().optional().default(true),\n showCustomUi: z.boolean().optional().default(true)\n});\n\nconst ProtectRangeSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n range: z.string().min(1, \"Range is required\"),\n description: z.string().optional(),\n warningOnly: z.boolean().optional().default(false)\n});\n\nconst AddNamedRangeSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n name: z.string().min(1, \"Name is required\"),\n range: z.string().min(1, \"Range is required\")\n});\n\nconst ListGoogleSheetsSchema = z.object({\n maxResults: z.number().int().min(1).max(100).optional().default(20),\n query: z.string().optional(),\n orderBy: z.enum([\"name\", \"modifiedTime\", \"createdTime\"]).optional().default(\"modifiedTime\")\n});\n\n// ---------------------------------------------------------------------------\n// Tool Definitions\n// ---------------------------------------------------------------------------\n\nexport const toolDefinitions: ToolDefinition[] = [\n {\n name: \"createGoogleSheet\",\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.\",\n inputSchema: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"Sheet name\" },\n data: {\n type: \"array\",\n description: \"Data as array of arrays\",\n items: { type: \"array\", items: { type: \"string\" } }\n },\n parentFolderId: { type: \"string\", description: \"Parent folder ID (defaults to root)\" },\n valueInputOption: {\n type: \"string\",\n enum: [\"RAW\", \"USER_ENTERED\"],\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().\"\n }\n },\n required: [\"name\", \"data\"]\n }\n },\n {\n name: \"updateGoogleSheet\",\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.\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Sheet ID\" },\n range: { type: \"string\", description: \"Range to update (e.g., 'Sheet1!A1:C10')\" },\n data: {\n type: \"array\",\n description: \"2D array of values to write\",\n items: { type: \"array\", items: { type: \"string\" } }\n },\n valueInputOption: {\n type: \"string\",\n enum: [\"RAW\", \"USER_ENTERED\"],\n description: \"RAW (default): Values stored exactly as provided - formulas stored as text strings. Safe for untrusted data. USER_ENTERED: Values parsed like spreadsheet UI - formulas (=SUM, =IF, etc.) are evaluated. SECURITY WARNING: USER_ENTERED can execute formulas, only use with trusted data, never with user-provided input that could contain malicious formulas like =IMPORTDATA() or =IMPORTRANGE().\"\n }\n },\n required: [\"spreadsheetId\", \"range\", \"data\"]\n }\n },\n {\n name: \"getGoogleSheetContent\",\n description: \"Get content of a Google Sheet with cell information\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\n range: { type: \"string\", description: \"Range to get (e.g., 'Sheet1!A1:C10')\" }\n },\n required: [\"spreadsheetId\", \"range\"]\n }\n },\n {\n name: \"formatGoogleSheetCells\",\n description: \"Format cells in a Google Sheet (background, borders, alignment)\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\n range: { type: \"string\", description: \"Range to format (e.g., 'A1:C10')\" },\n backgroundColor: {\n type: \"object\",\n description: \"Background color (RGB values 0-1)\",\n properties: {\n red: { type: \"number\" },\n green: { type: \"number\" },\n blue: { type: \"number\" }\n }\n },\n horizontalAlignment: {\n type: \"string\",\n description: \"Horizontal alignment\",\n enum: [\"LEFT\", \"CENTER\", \"RIGHT\"]\n },\n verticalAlignment: {\n type: \"string\",\n description: \"Vertical alignment\",\n enum: [\"TOP\", \"MIDDLE\", \"BOTTOM\"]\n },\n wrapStrategy: {\n type: \"string\",\n description: \"Text wrapping\",\n enum: [\"OVERFLOW_CELL\", \"CLIP\", \"WRAP\"]\n }\n },\n required: [\"spreadsheetId\", \"range\"]\n }\n },\n {\n name: \"formatGoogleSheetText\",\n description: \"Apply text formatting to cells in a Google Sheet\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\n range: { type: \"string\", description: \"Range to format (e.g., 'A1:C10')\" },\n bold: { type: \"boolean\", description: \"Make text bold\" },\n italic: { type: \"boolean\", description: \"Make text italic\" },\n strikethrough: { type: \"boolean\", description: \"Strikethrough text\" },\n underline: { type: \"boolean\", description: \"Underline text\" },\n fontSize: { type: \"number\", description: \"Font size in points\" },\n fontFamily: { type: \"string\", description: \"Font family name\" },\n foregroundColor: {\n type: \"object\",\n description: \"Text color (RGB values 0-1)\",\n properties: {\n red: { type: \"number\" },\n green: { type: \"number\" },\n blue: { type: \"number\" }\n }\n }\n },\n required: [\"spreadsheetId\", \"range\"]\n }\n },\n {\n name: \"formatGoogleSheetNumbers\",\n description: \"Apply number formatting to cells in a Google Sheet\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\n range: { type: \"string\", description: \"Range to format (e.g., 'A1:C10')\" },\n pattern: {\n type: \"string\",\n description: \"Number format pattern (e.g., '#,##0.00', 'yyyy-mm-dd', '$#,##0.00', '0.00%')\"\n },\n type: {\n type: \"string\",\n description: \"Format type\",\n enum: [\"NUMBER\", \"CURRENCY\", \"PERCENT\", \"DATE\", \"TIME\", \"DATE_TIME\", \"SCIENTIFIC\"]\n }\n },\n required: [\"spreadsheetId\", \"range\", \"pattern\"]\n }\n },\n {\n name: \"setGoogleSheetBorders\",\n description: \"Set borders for cells in a Google Sheet\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\n range: { type: \"string\", description: \"Range to format (e.g., 'A1:C10')\" },\n style: {\n type: \"string\",\n description: \"Border style\",\n enum: [\"SOLID\", \"DASHED\", \"DOTTED\", \"DOUBLE\"]\n },\n width: { type: \"number\", description: \"Border width (1-3)\" },\n color: {\n type: \"object\",\n description: \"Border color (RGB values 0-1)\",\n properties: {\n red: { type: \"number\" },\n green: { type: \"number\" },\n blue: { type: \"number\" }\n }\n },\n top: { type: \"boolean\", description: \"Apply to top border\" },\n bottom: { type: \"boolean\", description: \"Apply to bottom border\" },\n left: { type: \"boolean\", description: \"Apply to left border\" },\n right: { type: \"boolean\", description: \"Apply to right border\" },\n innerHorizontal: { type: \"boolean\", description: \"Apply to inner horizontal borders\" },\n innerVertical: { type: \"boolean\", description: \"Apply to inner vertical borders\" }\n },\n required: [\"spreadsheetId\", \"range\", \"style\"]\n }\n },\n {\n name: \"mergeGoogleSheetCells\",\n description: \"Merge cells in a Google Sheet\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\n range: { type: \"string\", description: \"Range to merge (e.g., 'A1:C3')\" },\n mergeType: {\n type: \"string\",\n description: \"Merge type\",\n enum: [\"MERGE_ALL\", \"MERGE_COLUMNS\", \"MERGE_ROWS\"]\n }\n },\n required: [\"spreadsheetId\", \"range\", \"mergeType\"]\n }\n },\n {\n name: \"addGoogleSheetConditionalFormat\",\n description: \"Add conditional formatting to a Google Sheet\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\n range: { type: \"string\", description: \"Range to apply formatting (e.g., 'A1:C10')\" },\n condition: {\n type: \"object\",\n description: \"Condition configuration\",\n properties: {\n type: {\n type: \"string\",\n description: \"Condition type\",\n enum: [\"NUMBER_GREATER\", \"NUMBER_LESS\", \"TEXT_CONTAINS\", \"TEXT_STARTS_WITH\", \"TEXT_ENDS_WITH\", \"CUSTOM_FORMULA\"]\n },\n value: { type: \"string\", description: \"Value to compare or formula\" }\n }\n },\n format: {\n type: \"object\",\n description: \"Format to apply when condition is true\",\n properties: {\n backgroundColor: {\n type: \"object\",\n properties: {\n red: { type: \"number\" },\n green: { type: \"number\" },\n blue: { type: \"number\" }\n }\n },\n textFormat: {\n type: \"object\",\n properties: {\n bold: { type: \"boolean\" },\n foregroundColor: {\n type: \"object\",\n properties: {\n red: { type: \"number\" },\n green: { type: \"number\" },\n blue: { type: \"number\" }\n }\n }\n }\n }\n }\n }\n },\n required: [\"spreadsheetId\", \"range\", \"condition\", \"format\"]\n }\n },\n {\n name: \"getSpreadsheetInfo\",\n description: \"Gets detailed information about a Google Spreadsheet including all sheets/tabs\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"The ID of the Google Spreadsheet (from the URL)\" }\n },\n required: [\"spreadsheetId\"]\n }\n },\n {\n name: \"appendSpreadsheetRows\",\n description: \"Appends rows of data to the end of a sheet in a Google Spreadsheet\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"The ID of the Google Spreadsheet (from the URL)\" },\n range: { type: \"string\", description: \"A1 notation range indicating where to append (e.g., 'A1' or 'Sheet1!A1'). Data will be appended starting from this range.\" },\n values: {\n type: \"array\",\n description: \"2D array of values to append. Each inner array represents a row.\",\n items: {\n type: \"array\",\n items: {\n anyOf: [\n { type: \"string\" },\n { type: \"number\" },\n { type: \"boolean\" },\n { type: \"null\" }\n ]\n }\n }\n },\n valueInputOption: { type: \"string\", description: \"How input data should be interpreted (RAW or USER_ENTERED)\", enum: [\"RAW\", \"USER_ENTERED\"], default: \"USER_ENTERED\" }\n },\n required: [\"spreadsheetId\", \"range\", \"values\"]\n }\n },\n {\n name: \"addSpreadsheetSheet\",\n description: \"Adds a new sheet/tab to an existing Google Spreadsheet\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"The ID of the Google Spreadsheet (from the URL)\" },\n sheetTitle: { type: \"string\", description: \"Title for the new sheet/tab\" }\n },\n required: [\"spreadsheetId\", \"sheetTitle\"]\n }\n },\n {\n name: \"addSheet\",\n description: \"Alias for addSpreadsheetSheet (adds a new sheet/tab)\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\n title: { type: \"string\", description: \"Title for the new sheet/tab\" }\n },\n required: [\"spreadsheetId\", \"title\"]\n }\n },\n {\n name: \"listSheets\",\n description: \"List tabs/sheets in a Google Spreadsheet\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" }\n },\n required: [\"spreadsheetId\"]\n }\n },\n {\n name: \"renameSheet\",\n description: \"Rename a sheet/tab by sheetId\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\n sheetId: { type: \"number\", description: \"Sheet ID\" },\n newTitle: { type: \"string\", description: \"New title\" }\n },\n required: [\"spreadsheetId\", \"sheetId\", \"newTitle\"]\n }\n },\n {\n name: \"deleteSheet\",\n description: \"Delete a sheet/tab by sheetId\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\n sheetId: { type: \"number\", description: \"Sheet ID\" }\n },\n required: [\"spreadsheetId\", \"sheetId\"]\n }\n },\n {\n name: \"addDataValidation\",\n description: \"Add data validation rules to a sheet range\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\n range: { type: \"string\", description: \"A1 range\" },\n conditionType: { type: \"string\", enum: [\"ONE_OF_LIST\", \"NUMBER_GREATER\", \"NUMBER_LESS\", \"TEXT_CONTAINS\"], description: \"Validation condition type\" },\n values: { type: \"array\", items: { type: \"string\" }, description: \"Condition values (e.g. list items, threshold)\" },\n strict: { type: \"boolean\", description: \"Reject invalid values\" },\n showCustomUi: { type: \"boolean\", description: \"Show dropdown/custom UI\" }\n },\n required: [\"spreadsheetId\", \"range\", \"conditionType\", \"values\"]\n }\n },\n {\n name: \"protectRange\",\n description: \"Protect a range in a spreadsheet\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\n range: { type: \"string\", description: \"A1 range\" },\n description: { type: \"string\", description: \"Protection description\" },\n warningOnly: { type: \"boolean\", description: \"Warn instead of enforce\" }\n },\n required: [\"spreadsheetId\", \"range\"]\n }\n },\n {\n name: \"addNamedRange\",\n description: \"Create a named range\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\n name: { type: \"string\", description: \"Named range name\" },\n range: { type: \"string\", description: \"A1 range\" }\n },\n required: [\"spreadsheetId\", \"name\", \"range\"]\n }\n },\n {\n name: \"listGoogleSheets\",\n description: \"Lists Google Spreadsheets from your Google Drive with optional filtering\",\n inputSchema: {\n type: \"object\",\n properties: {\n maxResults: { type: \"number\", description: \"Maximum number of spreadsheets to return (1-100)\", default: 20 },\n query: { type: \"string\", description: \"Search query to filter spreadsheets by name or content\" },\n orderBy: { type: \"string\", description: \"Sort order for results\", enum: [\"name\", \"modifiedTime\", \"createdTime\"], default: \"modifiedTime\" }\n },\n required: []\n }\n }\n];\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nasync function resolveGridRange(\n sheetsService: ReturnType<ToolContext['google']['sheets']>,\n spreadsheetId: string,\n range: string\n): Promise<GridRange | string> {\n const rangeData = await sheetsService.spreadsheets.get({\n spreadsheetId,\n ranges: [range],\n fields: 'sheets(properties(sheetId,title))'\n });\n const { sheetName, cellRange: a1Range } = parseA1Range(range);\n const sheet = rangeData.data.sheets?.find(s => s.properties?.title === sheetName);\n if (!sheet || sheet.properties?.sheetId === undefined || sheet.properties?.sheetId === null) {\n return `Sheet \"${sheetName}\" not found`;\n }\n return convertA1ToGridRange(a1Range, sheet.properties.sheetId!);\n}\n\n// ---------------------------------------------------------------------------\n// Handler\n// ---------------------------------------------------------------------------\n\nexport async function handleTool(\n toolName: string,\n args: Record<string, unknown>,\n ctx: ToolContext\n): Promise<ToolResult | null> {\n switch (toolName) {\n case \"createGoogleSheet\": {\n const validation = CreateGoogleSheetSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const parentFolderId = await ctx.resolveFolderId(a.parentFolderId);\n\n // Check if spreadsheet already exists\n const existingFileId = await ctx.checkFileExists(a.name, parentFolderId);\n if (existingFileId) {\n return errorResponse(\n `A spreadsheet named \"${a.name}\" already exists in this location. ` +\n `To update it, use updateGoogleSheet with spreadsheetId: ${existingFileId}`\n );\n }\n const sheets = ctx.google.sheets({ version: 'v4', auth: ctx.authClient });\n\n // Create spreadsheet with initial sheet\n const spreadsheet = await sheets.spreadsheets.create({\n requestBody: {\n properties: { title: a.name },\n sheets: [{\n properties: {\n sheetId: 0,\n title: 'Sheet1',\n gridProperties: {\n rowCount: Math.max(a.data.length, 1000),\n columnCount: Math.max(a.data[0]?.length || 0, 26)\n }\n }\n }]\n }\n });\n\n await ctx.getDrive().files.update({\n fileId: spreadsheet.data.spreadsheetId || '',\n addParents: parentFolderId,\n removeParents: 'root',\n fields: 'id, name, webViewLink',\n supportsAllDrives: true\n });\n\n // Now update with data\n await sheets.spreadsheets.values.update({\n spreadsheetId: spreadsheet.data.spreadsheetId!,\n range: 'Sheet1!A1',\n valueInputOption: a.valueInputOption || 'RAW',\n requestBody: { values: a.data }\n });\n\n return {\n content: [{ type: \"text\", text: `Created Google Sheet: ${a.name}\\nID: ${spreadsheet.data.spreadsheetId}` }],\n isError: false\n };\n }\n\n case \"updateGoogleSheet\": {\n const validation = UpdateGoogleSheetSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const sheets = ctx.google.sheets({ version: 'v4', auth: ctx.authClient });\n await sheets.spreadsheets.values.update({\n spreadsheetId: a.spreadsheetId,\n range: a.range,\n valueInputOption: a.valueInputOption || 'RAW',\n requestBody: { values: a.data }\n });\n\n return {\n content: [{ type: \"text\", text: `Updated Google Sheet range: ${a.range}` }],\n isError: false\n };\n }\n\n case \"getGoogleSheetContent\": {\n const validation = GetGoogleSheetContentSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const sheets = ctx.google.sheets({ version: 'v4', auth: ctx.authClient });\n const response = await sheets.spreadsheets.values.get({\n spreadsheetId: a.spreadsheetId,\n range: a.range\n });\n\n const values = response.data.values || [];\n let content = `Content for range ${a.range}:\\n\\n`;\n\n if (values.length === 0) {\n content += \"(empty range)\";\n } else {\n values.forEach((row, rowIndex) => {\n content += `Row ${rowIndex + 1}: ${row.join(', ')}\\n`;\n });\n }\n\n return {\n content: [{ type: \"text\", text: content }],\n isError: false\n };\n }\n\n case \"formatGoogleSheetCells\": {\n const validation = FormatGoogleSheetCellsSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const sheets = ctx.google.sheets({ version: 'v4', auth: ctx.authClient });\n\n // Parse the range to get sheet ID and grid range\n const rangeData = await sheets.spreadsheets.get({\n spreadsheetId: a.spreadsheetId,\n ranges: [a.range],\n fields: 'sheets(properties(sheetId,title))'\n });\n\n const { sheetName, cellRange: a1Range } = parseA1Range(a.range);\n\n const sheet = rangeData.data.sheets?.find(s => s.properties?.title === sheetName);\n\n if (!sheet || sheet.properties?.sheetId === undefined || sheet.properties?.sheetId === null) {\n return errorResponse(`Sheet \"${sheetName}\" not found`);\n }\n\n // Parse A1 notation to grid range\n const gridRange = convertA1ToGridRange(a1Range, sheet.properties.sheetId!);\n\n const requests: any[] = [{\n repeatCell: {\n range: gridRange,\n cell: {\n userEnteredFormat: {\n ...(a.backgroundColor && {\n backgroundColor: {\n red: a.backgroundColor.red || 0,\n green: a.backgroundColor.green || 0,\n blue: a.backgroundColor.blue || 0\n }\n }),\n ...(a.horizontalAlignment && { horizontalAlignment: a.horizontalAlignment }),\n ...(a.verticalAlignment && { verticalAlignment: a.verticalAlignment }),\n ...(a.wrapStrategy && { wrapStrategy: a.wrapStrategy })\n }\n },\n fields: [\n a.backgroundColor && 'userEnteredFormat.backgroundColor',\n a.horizontalAlignment && 'userEnteredFormat.horizontalAlignment',\n a.verticalAlignment && 'userEnteredFormat.verticalAlignment',\n a.wrapStrategy && 'userEnteredFormat.wrapStrategy'\n ].filter(Boolean).join(',')\n }\n }];\n\n await sheets.spreadsheets.batchUpdate({\n spreadsheetId: a.spreadsheetId,\n requestBody: { requests }\n });\n\n return {\n content: [{ type: \"text\", text: `Formatted cells in range ${a.range}` }],\n isError: false\n };\n }\n\n case \"formatGoogleSheetText\": {\n const validation = FormatGoogleSheetTextSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const sheets = ctx.google.sheets({ version: 'v4', auth: ctx.authClient });\n\n // Get sheet information\n const rangeData = await sheets.spreadsheets.get({\n spreadsheetId: a.spreadsheetId,\n ranges: [a.range],\n fields: 'sheets(properties(sheetId,title))'\n });\n\n const { sheetName, cellRange: a1Range } = parseA1Range(a.range);\n const sheet = rangeData.data.sheets?.find(s => s.properties?.title === sheetName);\n if (!sheet || sheet.properties?.sheetId === undefined || sheet.properties?.sheetId === null) {\n return errorResponse(`Sheet \"${sheetName}\" not found`);\n }\n\n const gridRange = convertA1ToGridRange(a1Range, sheet.properties.sheetId!);\n\n const textFormat: any = {};\n const fields: string[] = [];\n\n if (a.bold !== undefined) {\n textFormat.bold = a.bold;\n fields.push('bold');\n }\n if (a.italic !== undefined) {\n textFormat.italic = a.italic;\n fields.push('italic');\n }\n if (a.strikethrough !== undefined) {\n textFormat.strikethrough = a.strikethrough;\n fields.push('strikethrough');\n }\n if (a.underline !== undefined) {\n textFormat.underline = a.underline;\n fields.push('underline');\n }\n if (a.fontSize !== undefined) {\n textFormat.fontSize = a.fontSize;\n fields.push('fontSize');\n }\n if (a.fontFamily !== undefined) {\n textFormat.fontFamily = a.fontFamily;\n fields.push('fontFamily');\n }\n if (a.foregroundColor) {\n textFormat.foregroundColor = {\n red: a.foregroundColor.red || 0,\n green: a.foregroundColor.green || 0,\n blue: a.foregroundColor.blue || 0\n };\n fields.push('foregroundColor');\n }\n\n const requests = [{\n repeatCell: {\n range: gridRange,\n cell: {\n userEnteredFormat: { textFormat }\n },\n fields: 'userEnteredFormat.textFormat(' + fields.join(',') + ')'\n }\n }];\n\n await sheets.spreadsheets.batchUpdate({\n spreadsheetId: a.spreadsheetId,\n requestBody: { requests }\n });\n\n return {\n content: [{ type: \"text\", text: `Applied text formatting to range ${a.range}` }],\n isError: false\n };\n }\n\n case \"formatGoogleSheetNumbers\": {\n const validation = FormatGoogleSheetNumbersSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const sheets = ctx.google.sheets({ version: 'v4', auth: ctx.authClient });\n\n const rangeData = await sheets.spreadsheets.get({\n spreadsheetId: a.spreadsheetId,\n ranges: [a.range],\n fields: 'sheets(properties(sheetId,title))'\n });\n\n const { sheetName, cellRange: a1Range } = parseA1Range(a.range);\n const sheet = rangeData.data.sheets?.find(s => s.properties?.title === sheetName);\n if (!sheet || sheet.properties?.sheetId === undefined || sheet.properties?.sheetId === null) {\n return errorResponse(`Sheet \"${sheetName}\" not found`);\n }\n\n const gridRange = convertA1ToGridRange(a1Range, sheet.properties.sheetId!);\n\n const numberFormat: any = {\n pattern: a.pattern\n };\n if (a.type) {\n numberFormat.type = a.type;\n }\n\n const requests = [{\n repeatCell: {\n range: gridRange,\n cell: {\n userEnteredFormat: { numberFormat }\n },\n fields: 'userEnteredFormat.numberFormat'\n }\n }];\n\n await sheets.spreadsheets.batchUpdate({\n spreadsheetId: a.spreadsheetId,\n requestBody: { requests }\n });\n\n return {\n content: [{ type: \"text\", text: `Applied number formatting to range ${a.range}` }],\n isError: false\n };\n }\n\n case \"setGoogleSheetBorders\": {\n const validation = SetGoogleSheetBordersSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const sheets = ctx.google.sheets({ version: 'v4', auth: ctx.authClient });\n\n const rangeData = await sheets.spreadsheets.get({\n spreadsheetId: a.spreadsheetId,\n ranges: [a.range],\n fields: 'sheets(properties(sheetId,title))'\n });\n\n const { sheetName, cellRange: a1Range } = parseA1Range(a.range);\n const sheet = rangeData.data.sheets?.find(s => s.properties?.title === sheetName);\n if (!sheet || sheet.properties?.sheetId === undefined || sheet.properties?.sheetId === null) {\n return errorResponse(`Sheet \"${sheetName}\" not found`);\n }\n\n const gridRange = convertA1ToGridRange(a1Range, sheet.properties.sheetId!);\n\n const border = {\n style: a.style,\n width: a.width || 1,\n color: a.color ? {\n red: a.color.red || 0,\n green: a.color.green || 0,\n blue: a.color.blue || 0\n } : undefined\n };\n\n const updateBordersRequest: any = {\n updateBorders: {\n range: gridRange\n }\n };\n\n if (a.top !== false) updateBordersRequest.updateBorders.top = border;\n if (a.bottom !== false) updateBordersRequest.updateBorders.bottom = border;\n if (a.left !== false) updateBordersRequest.updateBorders.left = border;\n if (a.right !== false) updateBordersRequest.updateBorders.right = border;\n if (a.innerHorizontal) updateBordersRequest.updateBorders.innerHorizontal = border;\n if (a.innerVertical) updateBordersRequest.updateBorders.innerVertical = border;\n\n await sheets.spreadsheets.batchUpdate({\n spreadsheetId: a.spreadsheetId,\n requestBody: { requests: [updateBordersRequest] }\n });\n\n return {\n content: [{ type: \"text\", text: `Set borders for range ${a.range}` }],\n isError: false\n };\n }\n\n case \"mergeGoogleSheetCells\": {\n const validation = MergeGoogleSheetCellsSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const sheets = ctx.google.sheets({ version: 'v4', auth: ctx.authClient });\n\n const rangeData = await sheets.spreadsheets.get({\n spreadsheetId: a.spreadsheetId,\n ranges: [a.range],\n fields: 'sheets(properties(sheetId,title))'\n });\n\n const { sheetName, cellRange: a1Range } = parseA1Range(a.range);\n const sheet = rangeData.data.sheets?.find(s => s.properties?.title === sheetName);\n if (!sheet || sheet.properties?.sheetId === undefined || sheet.properties?.sheetId === null) {\n return errorResponse(`Sheet \"${sheetName}\" not found`);\n }\n\n const gridRange = convertA1ToGridRange(a1Range, sheet.properties.sheetId!);\n\n const requests = [{\n mergeCells: {\n range: gridRange,\n mergeType: a.mergeType\n }\n }];\n\n await sheets.spreadsheets.batchUpdate({\n spreadsheetId: a.spreadsheetId,\n requestBody: { requests }\n });\n\n return {\n content: [{ type: \"text\", text: `Merged cells in range ${a.range} with type ${a.mergeType}` }],\n isError: false\n };\n }\n\n case \"addGoogleSheetConditionalFormat\": {\n const validation = AddGoogleSheetConditionalFormatSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const sheets = ctx.google.sheets({ version: 'v4', auth: ctx.authClient });\n\n const rangeData = await sheets.spreadsheets.get({\n spreadsheetId: a.spreadsheetId,\n ranges: [a.range],\n fields: 'sheets(properties(sheetId,title))'\n });\n\n const { sheetName, cellRange: a1Range } = parseA1Range(a.range);\n const sheet = rangeData.data.sheets?.find(s => s.properties?.title === sheetName);\n if (!sheet || sheet.properties?.sheetId === undefined || sheet.properties?.sheetId === null) {\n return errorResponse(`Sheet \"${sheetName}\" not found`);\n }\n\n const gridRange = convertA1ToGridRange(a1Range, sheet.properties.sheetId!);\n\n // Build condition based on type\n const booleanCondition: any = {};\n switch (a.condition.type) {\n case 'NUMBER_GREATER':\n booleanCondition.type = 'NUMBER_GREATER';\n booleanCondition.values = [{ userEnteredValue: a.condition.value }];\n break;\n case 'NUMBER_LESS':\n booleanCondition.type = 'NUMBER_LESS';\n booleanCondition.values = [{ userEnteredValue: a.condition.value }];\n break;\n case 'TEXT_CONTAINS':\n booleanCondition.type = 'TEXT_CONTAINS';\n booleanCondition.values = [{ userEnteredValue: a.condition.value }];\n break;\n case 'TEXT_STARTS_WITH':\n booleanCondition.type = 'TEXT_STARTS_WITH';\n booleanCondition.values = [{ userEnteredValue: a.condition.value }];\n break;\n case 'TEXT_ENDS_WITH':\n booleanCondition.type = 'TEXT_ENDS_WITH';\n booleanCondition.values = [{ userEnteredValue: a.condition.value }];\n break;\n case 'CUSTOM_FORMULA':\n booleanCondition.type = 'CUSTOM_FORMULA';\n booleanCondition.values = [{ userEnteredValue: a.condition.value }];\n break;\n }\n\n const format: any = {};\n if (a.format.backgroundColor) {\n format.backgroundColor = {\n red: a.format.backgroundColor.red || 0,\n green: a.format.backgroundColor.green || 0,\n blue: a.format.backgroundColor.blue || 0\n };\n }\n if (a.format.textFormat) {\n format.textFormat = {};\n if (a.format.textFormat.bold !== undefined) {\n format.textFormat.bold = a.format.textFormat.bold;\n }\n if (a.format.textFormat.foregroundColor) {\n format.textFormat.foregroundColor = {\n red: a.format.textFormat.foregroundColor.red || 0,\n green: a.format.textFormat.foregroundColor.green || 0,\n blue: a.format.textFormat.foregroundColor.blue || 0\n };\n }\n }\n\n const requests = [{\n addConditionalFormatRule: {\n rule: {\n ranges: [gridRange],\n booleanRule: {\n condition: booleanCondition,\n format: format\n }\n },\n index: 0\n }\n }];\n\n await sheets.spreadsheets.batchUpdate({\n spreadsheetId: a.spreadsheetId,\n requestBody: { requests }\n });\n\n return {\n content: [{ type: \"text\", text: `Added conditional formatting to range ${a.range}` }],\n isError: false\n };\n }\n\n case \"getSpreadsheetInfo\": {\n const validation = GetSpreadsheetInfoSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const sheets = ctx.google.sheets({ version: 'v4', auth: ctx.authClient });\n const response = await sheets.spreadsheets.get({\n spreadsheetId: a.spreadsheetId,\n fields: 'spreadsheetId,properties.title,sheets.properties'\n });\n\n const metadata = response.data;\n let result = `**Spreadsheet Information:**\\n\\n`;\n result += `**Title:** ${metadata.properties?.title || 'Untitled'}\\n`;\n result += `**ID:** ${metadata.spreadsheetId}\\n`;\n result += `**URL:** https://docs.google.com/spreadsheets/d/${metadata.spreadsheetId}\\n\\n`;\n\n const sheetList = metadata.sheets || [];\n result += `**Sheets (${sheetList.length}):**\\n`;\n for (let i = 0; i < sheetList.length; i++) {\n const props = sheetList[i].properties;\n result += `${i + 1}. **${props?.title || 'Untitled'}**\\n`;\n result += ` - Sheet ID: ${props?.sheetId}\\n`;\n result += ` - Grid: ${props?.gridProperties?.rowCount || 0} rows \u00D7 ${props?.gridProperties?.columnCount || 0} columns\\n`;\n if (props?.hidden) {\n result += ` - Status: Hidden\\n`;\n }\n result += `\\n`;\n }\n\n return {\n content: [{ type: \"text\", text: result }],\n isError: false\n };\n }\n\n case \"appendSpreadsheetRows\": {\n const validation = AppendSpreadsheetRowsSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const sheets = ctx.google.sheets({ version: 'v4', auth: ctx.authClient });\n const response = await sheets.spreadsheets.values.append({\n spreadsheetId: a.spreadsheetId,\n range: a.range,\n valueInputOption: a.valueInputOption || 'USER_ENTERED',\n insertDataOption: 'INSERT_ROWS',\n requestBody: { values: a.values }\n });\n\n const updatedCells = response.data.updates?.updatedCells || 0;\n const updatedRows = response.data.updates?.updatedRows || 0;\n const updatedRange = response.data.updates?.updatedRange || a.range;\n\n return {\n content: [{ type: \"text\", text: `Successfully appended ${updatedRows} row(s) (${updatedCells} cells) to spreadsheet. Updated range: ${updatedRange}` }],\n isError: false\n };\n }\n\n case \"addSpreadsheetSheet\":\n case \"addSheet\": {\n const isAlias = toolName === 'addSheet';\n const validation = isAlias ? AddSheetSchema.safeParse(args) : AddSpreadsheetSheetSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n\n const spreadsheetId = validation.data.spreadsheetId;\n const sheetTitle = isAlias ? (validation.data as z.infer<typeof AddSheetSchema>).title : (validation.data as z.infer<typeof AddSpreadsheetSheetSchema>).sheetTitle;\n\n const sheets = ctx.google.sheets({ version: 'v4', auth: ctx.authClient });\n const response = await sheets.spreadsheets.batchUpdate({\n spreadsheetId,\n requestBody: {\n requests: [{\n addSheet: {\n properties: {\n title: sheetTitle\n }\n }\n }]\n }\n });\n\n const addedSheet = response.data.replies?.[0]?.addSheet?.properties;\n if (!addedSheet) {\n return errorResponse('Failed to add sheet - no sheet properties returned.');\n }\n\n return {\n content: [{ type: \"text\", text: `Successfully added sheet \"${addedSheet.title}\" (Sheet ID: ${addedSheet.sheetId}) to spreadsheet.` }],\n isError: false\n };\n }\n\n case \"listSheets\": {\n const validation = ListSheetsSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const a = validation.data;\n\n const sheets = ctx.google.sheets({ version: 'v4', auth: ctx.authClient });\n const response = await sheets.spreadsheets.get({\n spreadsheetId: a.spreadsheetId,\n fields: 'sheets.properties(sheetId,title,index,hidden)'\n });\n\n const tabs = response.data.sheets || [];\n if (tabs.length === 0) {\n return { content: [{ type: 'text', text: 'No sheets found.' }], isError: false };\n }\n\n const lines = tabs.map((s) => `- ${s.properties?.title} (id: ${s.properties?.sheetId}, index: ${s.properties?.index}${s.properties?.hidden ? ', hidden' : ''})`);\n return { content: [{ type: 'text', text: `Sheets in spreadsheet ${a.spreadsheetId}:\\n${lines.join('\\n')}` }], isError: false };\n }\n\n case \"renameSheet\": {\n const validation = RenameSheetSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const a = validation.data;\n\n const sheets = ctx.google.sheets({ version: 'v4', auth: ctx.authClient });\n await sheets.spreadsheets.batchUpdate({\n spreadsheetId: a.spreadsheetId,\n requestBody: {\n requests: [{\n updateSheetProperties: {\n properties: { sheetId: a.sheetId, title: a.newTitle },\n fields: 'title'\n }\n }]\n }\n });\n\n return { content: [{ type: 'text', text: `Renamed sheet ${a.sheetId} to \"${a.newTitle}\".` }], isError: false };\n }\n\n case \"deleteSheet\": {\n const validation = DeleteSheetSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const a = validation.data;\n\n const sheets = ctx.google.sheets({ version: 'v4', auth: ctx.authClient });\n await sheets.spreadsheets.batchUpdate({\n spreadsheetId: a.spreadsheetId,\n requestBody: {\n requests: [{\n deleteSheet: { sheetId: a.sheetId }\n }]\n }\n });\n\n return { content: [{ type: 'text', text: `Deleted sheet ${a.sheetId}.` }], isError: false };\n }\n\n case \"addDataValidation\": {\n const validation = AddDataValidationSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const a = validation.data;\n\n const sheets = ctx.google.sheets({ version: 'v4', auth: ctx.authClient });\n const gridRange = await resolveGridRange(sheets, a.spreadsheetId, a.range);\n if (typeof gridRange === 'string') return errorResponse(gridRange);\n\n const conditionValues = a.values.map(v => ({ userEnteredValue: v }));\n\n await sheets.spreadsheets.batchUpdate({\n spreadsheetId: a.spreadsheetId,\n requestBody: {\n requests: [{\n setDataValidation: {\n range: gridRange,\n rule: {\n condition: {\n type: a.conditionType,\n values: conditionValues,\n },\n strict: a.strict,\n showCustomUi: a.showCustomUi,\n },\n },\n }],\n },\n });\n\n return { content: [{ type: 'text', text: `Added data validation (${a.conditionType}) to ${a.range}.` }], isError: false };\n }\n\n case \"protectRange\": {\n const validation = ProtectRangeSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const a = validation.data;\n\n const sheets = ctx.google.sheets({ version: 'v4', auth: ctx.authClient });\n const gridRange = await resolveGridRange(sheets, a.spreadsheetId, a.range);\n if (typeof gridRange === 'string') return errorResponse(gridRange);\n\n const response = await sheets.spreadsheets.batchUpdate({\n spreadsheetId: a.spreadsheetId,\n requestBody: {\n requests: [{\n addProtectedRange: {\n protectedRange: {\n range: gridRange,\n description: a.description,\n warningOnly: a.warningOnly,\n },\n },\n }],\n },\n });\n\n const protectedRangeId = response.data.replies?.[0]?.addProtectedRange?.protectedRange?.protectedRangeId;\n return { content: [{ type: 'text', text: `Protected range ${a.range}${protectedRangeId ? ` (id: ${protectedRangeId})` : ''}.` }], isError: false };\n }\n\n case \"addNamedRange\": {\n const validation = AddNamedRangeSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const a = validation.data;\n\n const sheets = ctx.google.sheets({ version: 'v4', auth: ctx.authClient });\n const gridRange = await resolveGridRange(sheets, a.spreadsheetId, a.range);\n if (typeof gridRange === 'string') return errorResponse(gridRange);\n\n const response = await sheets.spreadsheets.batchUpdate({\n spreadsheetId: a.spreadsheetId,\n requestBody: {\n requests: [{\n addNamedRange: {\n namedRange: {\n name: a.name,\n range: gridRange,\n },\n },\n }],\n },\n });\n\n const namedRangeId = response.data.replies?.[0]?.addNamedRange?.namedRange?.namedRangeId;\n return { content: [{ type: 'text', text: `Added named range \"${a.name}\" for ${a.range}${namedRangeId ? ` (id: ${namedRangeId})` : ''}.` }], isError: false };\n }\n\n case \"listGoogleSheets\": {\n const validation = ListGoogleSheetsSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n let queryString = \"mimeType='application/vnd.google-apps.spreadsheet' and trashed=false\";\n if (a.query) {\n const escapedQuery = escapeDriveQuery(a.query);\n queryString += ` and (name contains '${escapedQuery}' or fullText contains '${escapedQuery}')`;\n }\n\n const response = await ctx.getDrive().files.list({\n q: queryString,\n pageSize: a.maxResults || 20,\n orderBy: a.orderBy === 'name' ? 'name' : a.orderBy,\n fields: 'files(id,name,modifiedTime,createdTime,webViewLink,owners(displayName,emailAddress))',\n supportsAllDrives: true,\n includeItemsFromAllDrives: true\n });\n\n const files = response.data.files || [];\n if (files.length === 0) {\n return {\n content: [{ type: \"text\", text: \"No Google Spreadsheets found matching your criteria.\" }],\n isError: false\n };\n }\n\n let result = `Found ${files.length} Google Spreadsheet(s):\\n\\n`;\n for (let i = 0; i < files.length; i++) {\n const file = files[i];\n const modifiedDate = file.modifiedTime ? new Date(file.modifiedTime).toLocaleDateString() : 'Unknown';\n const owner = file.owners?.[0]?.displayName || 'Unknown';\n result += `${i + 1}. **${file.name}**\\n`;\n result += ` ID: ${file.id}\\n`;\n result += ` Modified: ${modifiedDate}\\n`;\n result += ` Owner: ${owner}\\n`;\n result += ` Link: ${file.webViewLink}\\n\\n`;\n }\n\n return {\n content: [{ type: \"text\", text: result }],\n isError: false\n };\n }\n\n default:\n return null;\n }\n}\n", "import { z } from 'zod';\nimport { v4 as uuidv4 } from 'uuid';\nimport type { slides_v1 } from 'googleapis';\nimport type { ToolDefinition, ToolResult, ToolContext } from '../types.js';\nimport { errorResponse } from '../types.js';\nimport { uploadImageToDrive, deleteDriveFile } from '../utils/driveImageUpload.js';\n\n// ---------------------------------------------------------------------------\n// Zod Schemas\n// ---------------------------------------------------------------------------\n\nconst CreateGoogleSlidesSchema = z.object({\n name: z.string().min(1, \"Presentation name is required\"),\n slides: z.array(z.object({\n title: z.string(),\n content: z.string()\n })).min(1, \"At least one slide is required\"),\n parentFolderId: z.string().optional()\n});\n\nconst UpdateGoogleSlidesSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n slides: z.array(z.object({\n title: z.string(),\n content: z.string()\n })).min(1, \"At least one slide is required\")\n});\n\nconst GetGoogleSlidesContentSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n slideIndex: z.number().min(0).optional()\n});\n\nconst FormatGoogleSlidesTextSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n objectId: z.string().min(1, \"Object ID is required\"),\n startIndex: z.number().min(0).optional(),\n endIndex: z.number().min(0).optional(),\n bold: z.boolean().optional(),\n italic: z.boolean().optional(),\n underline: z.boolean().optional(),\n strikethrough: z.boolean().optional(),\n fontSize: z.number().optional(),\n fontFamily: z.string().optional(),\n foregroundColor: z.object({\n red: z.number().min(0).max(1).optional(),\n green: z.number().min(0).max(1).optional(),\n blue: z.number().min(0).max(1).optional()\n }).optional()\n});\n\nconst FormatGoogleSlidesParagraphSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n objectId: z.string().min(1, \"Object ID is required\"),\n alignment: z.enum(['START', 'CENTER', 'END', 'JUSTIFIED']).optional(),\n lineSpacing: z.number().optional(),\n bulletStyle: z.enum(['NONE', 'DISC', 'ARROW', 'SQUARE', 'DIAMOND', 'STAR', 'NUMBERED']).optional()\n});\n\nconst StyleGoogleSlidesShapeSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n objectId: z.string().min(1, \"Shape object ID is required\"),\n backgroundColor: z.object({\n red: z.number().min(0).max(1).optional(),\n green: z.number().min(0).max(1).optional(),\n blue: z.number().min(0).max(1).optional(),\n alpha: z.number().min(0).max(1).optional()\n }).optional(),\n outlineColor: z.object({\n red: z.number().min(0).max(1).optional(),\n green: z.number().min(0).max(1).optional(),\n blue: z.number().min(0).max(1).optional()\n }).optional(),\n outlineWeight: z.number().optional(),\n outlineDashStyle: z.enum(['SOLID', 'DOT', 'DASH', 'DASH_DOT', 'LONG_DASH', 'LONG_DASH_DOT']).optional()\n});\n\nconst SetGoogleSlidesBackgroundSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n pageObjectIds: z.array(z.string()).min(1, \"At least one page object ID is required\"),\n backgroundColor: z.object({\n red: z.number().min(0).max(1).optional(),\n green: z.number().min(0).max(1).optional(),\n blue: z.number().min(0).max(1).optional(),\n alpha: z.number().min(0).max(1).optional()\n })\n});\n\nconst CreateGoogleSlidesTextBoxSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n pageObjectId: z.string().min(1, \"Page object ID is required\"),\n text: z.string().min(1, \"Text content is required\"),\n x: z.number(),\n y: z.number(),\n width: z.number(),\n height: z.number(),\n fontSize: z.number().optional(),\n bold: z.boolean().optional(),\n italic: z.boolean().optional()\n});\n\nconst CreateGoogleSlidesShapeSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n pageObjectId: z.string().min(1, \"Page object ID is required\"),\n shapeType: z.enum(['RECTANGLE', 'ELLIPSE', 'DIAMOND', 'TRIANGLE', 'STAR', 'ROUND_RECTANGLE', 'ARROW']),\n x: z.number(),\n y: z.number(),\n width: z.number(),\n height: z.number(),\n backgroundColor: z.object({\n red: z.number().min(0).max(1).optional(),\n green: z.number().min(0).max(1).optional(),\n blue: z.number().min(0).max(1).optional(),\n alpha: z.number().min(0).max(1).optional()\n }).optional()\n});\n\nconst GetGoogleSlidesSpeakerNotesSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n slideIndex: z.number().min(0, \"Slide index must be non-negative\")\n});\n\nconst UpdateGoogleSlidesSpeakerNotesSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n slideIndex: z.number().min(0, \"Slide index must be non-negative\"),\n notes: z.string()\n});\n\nconst DeleteGoogleSlideSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n slideObjectId: z.string().min(1, \"Slide object ID is required\")\n});\n\nconst DuplicateSlideSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n slideObjectId: z.string().min(1, \"Slide object ID is required\")\n});\n\nconst ReorderSlidesSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n slideObjectIds: z.array(z.string().min(1)).min(1, \"At least one slide object ID is required\"),\n insertionIndex: z.number().int().min(0)\n});\n\nconst ReplaceAllTextInSlidesSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n containsText: z.string().min(1, \"containsText is required\"),\n replaceText: z.string(),\n matchCase: z.boolean().optional().default(false)\n});\n\nconst ExportSlideThumbnailSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n slideObjectId: z.string().min(1, \"Slide object ID is required\"),\n mimeType: z.enum([\"PNG\", \"JPEG\"]).optional().default(\"PNG\"),\n size: z.enum([\"SMALL\", \"MEDIUM\", \"LARGE\"]).optional().default(\"LARGE\")\n});\n\nconst InsertSlidesImageFromUrlSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n pageObjectId: z.string().min(1, \"Slide/page object ID is required\"),\n imageUrl: z.string().url(\"A valid image URL is required\"),\n x: z.number().optional().default(0),\n y: z.number().optional().default(0),\n width: z.number().optional(),\n height: z.number().optional(),\n});\n\nconst MoveSlideElementSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n objectId: z.string().min(1, \"Element object ID is required\"),\n x: z.number().optional(),\n y: z.number().optional(),\n width: z.number().optional(),\n height: z.number().optional(),\n});\n\nconst DeleteSlideElementSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n objectId: z.string().min(1, \"Element object ID is required\"),\n});\n\nconst GetSlideElementInfoSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n slideObjectId: z.string().optional(),\n});\n\nconst InsertSlidesLocalImageSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n pageObjectId: z.string().min(1, \"Slide/page object ID is required\"),\n localImagePath: z.string().min(1, \"Local image path is required\"),\n x: z.number().optional().default(0),\n y: z.number().optional().default(0),\n width: z.number().optional(),\n height: z.number().optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nasync function insertImageIntoSlide(\n ctx: ToolContext,\n presentationId: string,\n pageObjectId: string,\n imageUrl: string,\n x: number,\n y: number,\n width?: number,\n height?: number,\n): Promise<ToolResult> {\n const slidesService = ctx.google.slides({ version: 'v1', auth: ctx.authClient });\n const objectId = `img_${uuidv4().substring(0, 8)}`;\n\n const elementProperties: slides_v1.Schema$PageElementProperties = {\n pageObjectId,\n transform: {\n scaleX: 1,\n scaleY: 1,\n translateX: x,\n translateY: y,\n unit: 'EMU',\n },\n };\n\n if (width != null && height != null) {\n elementProperties.size = {\n width: { magnitude: width, unit: 'EMU' },\n height: { magnitude: height, unit: 'EMU' },\n };\n }\n\n await slidesService.presentations.batchUpdate({\n presentationId,\n requestBody: {\n requests: [{\n createImage: { objectId, url: imageUrl, elementProperties },\n }],\n },\n });\n\n return {\n content: [{ type: 'text', text: `Inserted image into slide ${pageObjectId} (objectId: ${objectId})` }],\n isError: false,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Tool Definitions\n// ---------------------------------------------------------------------------\n\nexport const toolDefinitions: ToolDefinition[] = [\n {\n name: \"createGoogleSlides\",\n description: \"Create a new Google Slides presentation\",\n inputSchema: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"Presentation name\" },\n slides: {\n type: \"array\",\n description: \"Array of slide objects\",\n items: {\n type: \"object\",\n properties: {\n title: { type: \"string\" },\n content: { type: \"string\" }\n }\n }\n },\n parentFolderId: { type: \"string\", description: \"Parent folder ID (defaults to root)\" }\n },\n required: [\"name\", \"slides\"]\n }\n },\n {\n name: \"updateGoogleSlides\",\n description: \"Update an existing Google Slides presentation\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n slides: {\n type: \"array\",\n description: \"Array of slide objects to replace existing slides\",\n items: {\n type: \"object\",\n properties: {\n title: { type: \"string\" },\n content: { type: \"string\" }\n }\n }\n }\n },\n required: [\"presentationId\", \"slides\"]\n }\n },\n {\n name: \"getGoogleSlidesContent\",\n description: \"Get content of Google Slides with element IDs for formatting\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n slideIndex: { type: \"number\", description: \"Specific slide index (optional)\" }\n },\n required: [\"presentationId\"]\n }\n },\n {\n name: \"formatGoogleSlidesText\",\n description: \"Apply text formatting to elements in Google Slides\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n objectId: { type: \"string\", description: \"Object ID of the text element\" },\n startIndex: { type: \"number\", description: \"Start index (0-based)\" },\n endIndex: { type: \"number\", description: \"End index (0-based)\" },\n bold: { type: \"boolean\", description: \"Make text bold\" },\n italic: { type: \"boolean\", description: \"Make text italic\" },\n underline: { type: \"boolean\", description: \"Underline text\" },\n strikethrough: { type: \"boolean\", description: \"Strikethrough text\" },\n fontSize: { type: \"number\", description: \"Font size in points\" },\n fontFamily: { type: \"string\", description: \"Font family name\" },\n foregroundColor: {\n type: \"object\",\n description: \"Text color (RGB values 0-1)\",\n properties: {\n red: { type: \"number\" },\n green: { type: \"number\" },\n blue: { type: \"number\" }\n }\n }\n },\n required: [\"presentationId\", \"objectId\"]\n }\n },\n {\n name: \"formatGoogleSlidesParagraph\",\n description: \"Apply paragraph formatting to text in Google Slides\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n objectId: { type: \"string\", description: \"Object ID of the text element\" },\n alignment: {\n type: \"string\",\n description: \"Text alignment\",\n enum: [\"START\", \"CENTER\", \"END\", \"JUSTIFIED\"]\n },\n lineSpacing: { type: \"number\", description: \"Line spacing multiplier\" },\n bulletStyle: {\n type: \"string\",\n description: \"Bullet style\",\n enum: [\"NONE\", \"DISC\", \"ARROW\", \"SQUARE\", \"DIAMOND\", \"STAR\", \"NUMBERED\"]\n }\n },\n required: [\"presentationId\", \"objectId\"]\n }\n },\n {\n name: \"styleGoogleSlidesShape\",\n description: \"Style shapes in Google Slides\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n objectId: { type: \"string\", description: \"Shape object ID\" },\n backgroundColor: {\n type: \"object\",\n description: \"Background color (RGBA values 0-1)\",\n properties: {\n red: { type: \"number\" },\n green: { type: \"number\" },\n blue: { type: \"number\" },\n alpha: { type: \"number\" }\n }\n },\n outlineColor: {\n type: \"object\",\n description: \"Outline color (RGB values 0-1)\",\n properties: {\n red: { type: \"number\" },\n green: { type: \"number\" },\n blue: { type: \"number\" }\n }\n },\n outlineWeight: { type: \"number\", description: \"Outline thickness in points\" },\n outlineDashStyle: {\n type: \"string\",\n description: \"Outline dash style\",\n enum: [\"SOLID\", \"DOT\", \"DASH\", \"DASH_DOT\", \"LONG_DASH\", \"LONG_DASH_DOT\"]\n }\n },\n required: [\"presentationId\", \"objectId\"]\n }\n },\n {\n name: \"setGoogleSlidesBackground\",\n description: \"Set background color for slides\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n pageObjectIds: {\n type: \"array\",\n description: \"Array of slide IDs to update\",\n items: { type: \"string\" }\n },\n backgroundColor: {\n type: \"object\",\n description: \"Background color (RGBA values 0-1)\",\n properties: {\n red: { type: \"number\" },\n green: { type: \"number\" },\n blue: { type: \"number\" },\n alpha: { type: \"number\" }\n }\n }\n },\n required: [\"presentationId\", \"pageObjectIds\", \"backgroundColor\"]\n }\n },\n {\n name: \"createGoogleSlidesTextBox\",\n description: \"Create a text box in Google Slides\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n pageObjectId: { type: \"string\", description: \"Slide ID\" },\n text: { type: \"string\", description: \"Text content\" },\n x: { type: \"number\", description: \"X position in EMU (1/360000 cm)\" },\n y: { type: \"number\", description: \"Y position in EMU\" },\n width: { type: \"number\", description: \"Width in EMU\" },\n height: { type: \"number\", description: \"Height in EMU\" },\n fontSize: { type: \"number\", description: \"Font size in points\" },\n bold: { type: \"boolean\", description: \"Make text bold\" },\n italic: { type: \"boolean\", description: \"Make text italic\" }\n },\n required: [\"presentationId\", \"pageObjectId\", \"text\", \"x\", \"y\", \"width\", \"height\"]\n }\n },\n {\n name: \"createGoogleSlidesShape\",\n description: \"Create a shape in Google Slides\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n pageObjectId: { type: \"string\", description: \"Slide ID\" },\n shapeType: {\n type: \"string\",\n description: \"Shape type\",\n enum: [\"RECTANGLE\", \"ELLIPSE\", \"DIAMOND\", \"TRIANGLE\", \"STAR\", \"ROUND_RECTANGLE\", \"ARROW\"]\n },\n x: { type: \"number\", description: \"X position in EMU\" },\n y: { type: \"number\", description: \"Y position in EMU\" },\n width: { type: \"number\", description: \"Width in EMU\" },\n height: { type: \"number\", description: \"Height in EMU\" },\n backgroundColor: {\n type: \"object\",\n description: \"Fill color (RGBA values 0-1)\",\n properties: {\n red: { type: \"number\" },\n green: { type: \"number\" },\n blue: { type: \"number\" },\n alpha: { type: \"number\" }\n }\n }\n },\n required: [\"presentationId\", \"pageObjectId\", \"shapeType\", \"x\", \"y\", \"width\", \"height\"]\n }\n },\n {\n name: \"getGoogleSlidesSpeakerNotes\",\n description: \"Get speaker notes from a specific slide in Google Slides\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n slideIndex: { type: \"number\", description: \"Slide index (0-based)\" }\n },\n required: [\"presentationId\", \"slideIndex\"]\n }\n },\n {\n name: \"updateGoogleSlidesSpeakerNotes\",\n description: \"Update speaker notes for a specific slide in Google Slides\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n slideIndex: { type: \"number\", description: \"Slide index (0-based)\" },\n notes: { type: \"string\", description: \"Speaker notes content\" }\n },\n required: [\"presentationId\", \"slideIndex\", \"notes\"]\n }\n },\n {\n name: \"deleteGoogleSlide\",\n description: \"Delete a slide from a presentation\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n slideObjectId: { type: \"string\", description: \"Slide object ID\" }\n },\n required: [\"presentationId\", \"slideObjectId\"]\n }\n },\n {\n name: \"duplicateSlide\",\n description: \"Duplicate a slide in a presentation\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n slideObjectId: { type: \"string\", description: \"Slide object ID\" }\n },\n required: [\"presentationId\", \"slideObjectId\"]\n }\n },\n {\n name: \"reorderSlides\",\n description: \"Reorder one or more slides in a presentation\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n slideObjectIds: { type: \"array\", items: { type: \"string\" }, description: \"Slide object IDs to move\" },\n insertionIndex: { type: \"number\", description: \"Target insertion index\" }\n },\n required: [\"presentationId\", \"slideObjectIds\", \"insertionIndex\"]\n }\n },\n {\n name: \"replaceAllTextInSlides\",\n description: \"Replace all matching text across presentation slides\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n containsText: { type: \"string\", description: \"Text to find\" },\n replaceText: { type: \"string\", description: \"Replacement text\" },\n matchCase: { type: \"boolean\", description: \"Case-sensitive match\" }\n },\n required: [\"presentationId\", \"containsText\", \"replaceText\"]\n }\n },\n {\n name: \"exportSlideThumbnail\",\n description: \"Export a slide thumbnail URL\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n slideObjectId: { type: \"string\", description: \"Slide object ID\" },\n mimeType: { type: \"string\", enum: [\"PNG\", \"JPEG\"], description: \"Thumbnail MIME type\" },\n size: { type: \"string\", enum: [\"SMALL\", \"MEDIUM\", \"LARGE\"], description: \"Thumbnail size\" }\n },\n required: [\"presentationId\", \"slideObjectId\"]\n }\n },\n {\n name: \"insertSlidesImageFromUrl\",\n description: \"Insert an image into a Google Slides slide from a publicly accessible URL\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n pageObjectId: { type: \"string\", description: \"Slide/page object ID to insert the image into\" },\n imageUrl: { type: \"string\", description: \"Publicly accessible URL of the image\" },\n x: { type: \"number\", description: \"X position in EMU (default: 0)\" },\n y: { type: \"number\", description: \"Y position in EMU (default: 0)\" },\n width: { type: \"number\", description: \"Width in EMU (omit to auto-size)\" },\n height: { type: \"number\", description: \"Height in EMU (omit to auto-size)\" }\n },\n required: [\"presentationId\", \"pageObjectId\", \"imageUrl\"]\n }\n },\n {\n name: \"getSlideElementInfo\",\n description: \"Get position, size, and transform of all elements on a slide. Returns actual rendered bounds.\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n slideObjectId: { type: \"string\", description: \"Slide object ID (omit to get all slides)\" }\n },\n required: [\"presentationId\"]\n }\n },\n {\n name: \"moveSlideElement\",\n description: \"Move and/or resize an element (image, text box, shape) on a Google Slides slide\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n objectId: { type: \"string\", description: \"Element object ID to move/resize\" },\n x: { type: \"number\", description: \"New X position in EMU\" },\n y: { type: \"number\", description: \"New Y position in EMU\" },\n width: { type: \"number\", description: \"New width in EMU\" },\n height: { type: \"number\", description: \"New height in EMU\" }\n },\n required: [\"presentationId\", \"objectId\"]\n }\n },\n {\n name: \"deleteSlideElement\",\n description: \"Delete an element (image, text box, shape) from a Google Slides slide\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n objectId: { type: \"string\", description: \"Element object ID to delete\" }\n },\n required: [\"presentationId\", \"objectId\"]\n }\n },\n {\n name: \"insertSlidesLocalImage\",\n description: \"Upload a local image file to Google Drive and insert it into a Google Slides slide\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n pageObjectId: { type: \"string\", description: \"Slide/page object ID to insert the image into\" },\n localImagePath: { type: \"string\", description: \"Absolute path to the local image file\" },\n x: { type: \"number\", description: \"X position in EMU (default: 0)\" },\n y: { type: \"number\", description: \"Y position in EMU (default: 0)\" },\n width: { type: \"number\", description: \"Width in EMU (omit to auto-size)\" },\n height: { type: \"number\", description: \"Height in EMU (omit to auto-size)\" }\n },\n required: [\"presentationId\", \"pageObjectId\", \"localImagePath\"]\n }\n },\n];\n\n// ---------------------------------------------------------------------------\n// Handler\n// ---------------------------------------------------------------------------\n\nexport async function handleTool(\n toolName: string,\n args: Record<string, unknown>,\n ctx: ToolContext\n): Promise<ToolResult | null> {\n switch (toolName) {\n\n case \"createGoogleSlides\": {\n const validation = CreateGoogleSlidesSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const parentFolderId = await ctx.resolveFolderId(a.parentFolderId);\n\n // Check if presentation already exists\n const existingFileId = await ctx.checkFileExists(a.name, parentFolderId);\n if (existingFileId) {\n return errorResponse(\n `A presentation named \"${a.name}\" already exists in this location. ` +\n `File ID: ${existingFileId}. To modify it, you can use Google Slides directly.`\n );\n }\n\n const slidesService = ctx.google.slides({ version: 'v1', auth: ctx.authClient });\n const presentation = await slidesService.presentations.create({\n requestBody: { title: a.name },\n });\n\n await ctx.getDrive().files.update({\n fileId: presentation.data.presentationId!,\n addParents: parentFolderId,\n removeParents: 'root',\n supportsAllDrives: true\n });\n\n for (const slide of a.slides) {\n const slideObjectId = `slide_${uuidv4().substring(0, 8)}`;\n await slidesService.presentations.batchUpdate({\n presentationId: presentation.data.presentationId!,\n requestBody: {\n requests: [{\n createSlide: {\n objectId: slideObjectId,\n slideLayoutReference: { predefinedLayout: 'TITLE_AND_BODY' },\n }\n }]\n },\n });\n\n const slidePage = await slidesService.presentations.pages.get({\n presentationId: presentation.data.presentationId!,\n pageObjectId: slideObjectId,\n });\n\n let titlePlaceholderId = '';\n let bodyPlaceholderId = '';\n slidePage.data.pageElements?.forEach((el) => {\n if (el.shape?.placeholder?.type === 'TITLE') {\n titlePlaceholderId = el.objectId!;\n } else if (el.shape?.placeholder?.type === 'BODY') {\n bodyPlaceholderId = el.objectId!;\n }\n });\n\n await slidesService.presentations.batchUpdate({\n presentationId: presentation.data.presentationId!,\n requestBody: {\n requests: [\n { insertText: { objectId: titlePlaceholderId, text: slide.title, insertionIndex: 0 } },\n { insertText: { objectId: bodyPlaceholderId, text: slide.content, insertionIndex: 0 } }\n ]\n },\n });\n }\n\n return {\n content: [{\n type: 'text',\n text: `Created Google Slides presentation: ${a.name}\\nID: ${presentation.data.presentationId}\\nLink: https://docs.google.com/presentation/d/${presentation.data.presentationId}`,\n }],\n isError: false,\n };\n }\n\n case \"updateGoogleSlides\": {\n const validation = UpdateGoogleSlidesSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const slidesService = ctx.google.slides({ version: 'v1', auth: ctx.authClient });\n\n // Get current presentation details\n const currentPresentation = await slidesService.presentations.get({\n presentationId: a.presentationId\n });\n\n if (!currentPresentation.data.slides) {\n return errorResponse(\"No slides found in presentation\");\n }\n\n // Collect all slide IDs except the first one (we'll keep it for now)\n const slideIdsToDelete = currentPresentation.data.slides\n .slice(1)\n .map(slide => slide.objectId)\n .filter((id): id is string => id !== undefined);\n\n // Prepare requests to update presentation\n const requests: any[] = [];\n\n // Delete all slides except the first one\n if (slideIdsToDelete.length > 0) {\n slideIdsToDelete.forEach(slideId => {\n requests.push({\n deleteObject: { objectId: slideId }\n });\n });\n }\n\n // Now we need to update the first slide or create new slides\n if (a.slides.length === 0) {\n return errorResponse(\"At least one slide must be provided\");\n }\n\n // Clear content of the first slide\n const firstSlide = currentPresentation.data.slides[0];\n if (firstSlide && firstSlide.pageElements) {\n // Find text elements to clear\n firstSlide.pageElements.forEach(element => {\n if (element.objectId && element.shape?.text) {\n requests.push({\n deleteText: {\n objectId: element.objectId,\n textRange: { type: 'ALL' }\n }\n });\n }\n });\n }\n\n // Update the first slide with new content\n const firstSlideContent = a.slides[0];\n if (firstSlide && firstSlide.pageElements) {\n // Find title and body placeholders\n let titlePlaceholderId: string | undefined;\n let bodyPlaceholderId: string | undefined;\n\n firstSlide.pageElements.forEach(element => {\n if (element.shape?.placeholder?.type === 'TITLE' || element.shape?.placeholder?.type === 'CENTERED_TITLE') {\n titlePlaceholderId = element.objectId || undefined;\n } else if (element.shape?.placeholder?.type === 'BODY' || element.shape?.placeholder?.type === 'SUBTITLE') {\n bodyPlaceholderId = element.objectId || undefined;\n }\n });\n\n if (titlePlaceholderId) {\n requests.push({\n insertText: {\n objectId: titlePlaceholderId,\n text: firstSlideContent.title,\n insertionIndex: 0\n }\n });\n }\n\n if (bodyPlaceholderId) {\n requests.push({\n insertText: {\n objectId: bodyPlaceholderId,\n text: firstSlideContent.content,\n insertionIndex: 0\n }\n });\n }\n }\n\n // Add any additional slides from the request\n for (let i = 1; i < a.slides.length; i++) {\n const slideId = `slide_${Date.now()}_${i}`;\n\n requests.push({\n createSlide: {\n objectId: slideId,\n slideLayoutReference: {\n predefinedLayout: 'TITLE_AND_BODY'\n }\n }\n });\n\n // We'll need to add content to these slides in a separate batch update\n // because we need to wait for the slides to be created first\n }\n\n // Execute the batch update\n await slidesService.presentations.batchUpdate({\n presentationId: a.presentationId,\n requestBody: { requests }\n });\n\n // If we have additional slides, add their content\n if (a.slides.length > 1) {\n const contentRequests: any[] = [];\n\n // Get updated presentation to find the new slide IDs\n const updatedPresentation = await slidesService.presentations.get({\n presentationId: a.presentationId\n });\n\n // Add content to the new slides (starting from the second slide in our args)\n for (let i = 1; i < a.slides.length && updatedPresentation.data.slides; i++) {\n const slide = a.slides[i];\n const presentationSlide = updatedPresentation.data.slides[i];\n\n if (presentationSlide && presentationSlide.pageElements) {\n presentationSlide.pageElements.forEach(element => {\n if (element.objectId) {\n if (element.shape?.placeholder?.type === 'TITLE' || element.shape?.placeholder?.type === 'CENTERED_TITLE') {\n contentRequests.push({\n insertText: {\n objectId: element.objectId,\n text: slide.title,\n insertionIndex: 0\n }\n });\n } else if (element.shape?.placeholder?.type === 'BODY' || element.shape?.placeholder?.type === 'SUBTITLE') {\n contentRequests.push({\n insertText: {\n objectId: element.objectId,\n text: slide.content,\n insertionIndex: 0\n }\n });\n }\n }\n });\n }\n }\n\n if (contentRequests.length > 0) {\n await slidesService.presentations.batchUpdate({\n presentationId: a.presentationId,\n requestBody: { requests: contentRequests }\n });\n }\n }\n\n return {\n content: [{\n type: 'text',\n text: `Updated Google Slides presentation with ${a.slides.length} slide(s)\\nLink: https://docs.google.com/presentation/d/${a.presentationId}`,\n }],\n isError: false,\n };\n }\n\n case \"getGoogleSlidesContent\": {\n const validation = GetGoogleSlidesContentSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const slidesService = ctx.google.slides({ version: 'v1', auth: ctx.authClient });\n const presentation = await slidesService.presentations.get({\n presentationId: a.presentationId\n });\n\n if (!presentation.data.slides) {\n return errorResponse(\"No slides found in presentation\");\n }\n\n let content = 'Presentation content with element IDs:\\n\\n';\n const slides = a.slideIndex !== undefined\n ? [presentation.data.slides[a.slideIndex]]\n : presentation.data.slides;\n\n slides.forEach((slide, index) => {\n if (!slide || !slide.objectId) return;\n\n content += `\\nSlide ${a.slideIndex ?? index} (ID: ${slide.objectId}):\\n`;\n content += '----------------------------\\n';\n\n if (slide.pageElements) {\n slide.pageElements.forEach((element) => {\n if (!element.objectId) return;\n\n if (element.shape?.text) {\n content += ` Text Box (ID: ${element.objectId}):\\n`;\n const textElements = element.shape.text.textElements || [];\n let text = '';\n textElements.forEach((textElement) => {\n if (textElement.textRun?.content) {\n text += textElement.textRun.content;\n }\n });\n content += ` \"${text.trim()}\"\\n`;\n } else if (element.shape) {\n content += ` Shape (ID: ${element.objectId}): ${element.shape.shapeType || 'Unknown'}\\n`;\n } else if (element.image) {\n content += ` Image (ID: ${element.objectId})\\n`;\n } else if (element.video) {\n content += ` Video (ID: ${element.objectId})\\n`;\n } else if (element.table) {\n content += ` Table (ID: ${element.objectId})\\n`;\n }\n });\n }\n });\n\n return {\n content: [{ type: \"text\", text: content }],\n isError: false\n };\n }\n\n case \"formatGoogleSlidesText\": {\n const validation = FormatGoogleSlidesTextSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const slidesService = ctx.google.slides({ version: 'v1', auth: ctx.authClient });\n const textStyle: any = {};\n const fields: string[] = [];\n\n if (a.bold !== undefined) {\n textStyle.bold = a.bold;\n fields.push('bold');\n }\n\n if (a.italic !== undefined) {\n textStyle.italic = a.italic;\n fields.push('italic');\n }\n\n if (a.underline !== undefined) {\n textStyle.underline = a.underline;\n fields.push('underline');\n }\n\n if (a.strikethrough !== undefined) {\n textStyle.strikethrough = a.strikethrough;\n fields.push('strikethrough');\n }\n\n if (a.fontSize !== undefined) {\n textStyle.fontSize = {\n magnitude: a.fontSize,\n unit: 'PT'\n };\n fields.push('fontSize');\n }\n\n if (a.fontFamily !== undefined) {\n textStyle.fontFamily = a.fontFamily;\n fields.push('fontFamily');\n }\n\n if (a.foregroundColor) {\n textStyle.foregroundColor = {\n opaqueColor: {\n rgbColor: {\n red: a.foregroundColor.red || 0,\n green: a.foregroundColor.green || 0,\n blue: a.foregroundColor.blue || 0\n }\n }\n };\n fields.push('foregroundColor');\n }\n\n if (fields.length === 0) {\n return errorResponse(\"No formatting options specified\");\n }\n\n const updateRequest: any = {\n updateTextStyle: {\n objectId: a.objectId,\n style: textStyle,\n fields: fields.join(',')\n }\n };\n\n // Add text range if specified\n if (a.startIndex !== undefined && a.endIndex !== undefined) {\n updateRequest.updateTextStyle.textRange = {\n type: 'FIXED_RANGE',\n startIndex: a.startIndex,\n endIndex: a.endIndex\n };\n } else {\n updateRequest.updateTextStyle.textRange = { type: 'ALL' };\n }\n\n await slidesService.presentations.batchUpdate({\n presentationId: a.presentationId,\n requestBody: { requests: [updateRequest] }\n });\n\n return {\n content: [{ type: \"text\", text: `Applied text formatting to object ${a.objectId}` }],\n isError: false\n };\n }\n\n case \"formatGoogleSlidesParagraph\": {\n const validation = FormatGoogleSlidesParagraphSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const slidesService = ctx.google.slides({ version: 'v1', auth: ctx.authClient });\n const requests: any[] = [];\n\n if (a.alignment) {\n requests.push({\n updateParagraphStyle: {\n objectId: a.objectId,\n style: { alignment: a.alignment },\n fields: 'alignment'\n }\n });\n }\n\n if (a.lineSpacing !== undefined) {\n requests.push({\n updateParagraphStyle: {\n objectId: a.objectId,\n style: { lineSpacing: a.lineSpacing },\n fields: 'lineSpacing'\n }\n });\n }\n\n if (a.bulletStyle) {\n if (a.bulletStyle === 'NONE') {\n requests.push({\n deleteParagraphBullets: {\n objectId: a.objectId\n }\n });\n } else if (a.bulletStyle === 'NUMBERED') {\n requests.push({\n createParagraphBullets: {\n objectId: a.objectId,\n bulletPreset: 'NUMBERED_DIGIT_ALPHA_ROMAN'\n }\n });\n } else {\n requests.push({\n createParagraphBullets: {\n objectId: a.objectId,\n bulletPreset: `BULLET_${a.bulletStyle}_CIRCLE_SQUARE`\n }\n });\n }\n }\n\n if (requests.length === 0) {\n return errorResponse(\"No formatting options specified\");\n }\n\n await slidesService.presentations.batchUpdate({\n presentationId: a.presentationId,\n requestBody: { requests }\n });\n\n return {\n content: [{ type: \"text\", text: `Applied paragraph formatting to object ${a.objectId}` }],\n isError: false\n };\n }\n\n case \"styleGoogleSlidesShape\": {\n const validation = StyleGoogleSlidesShapeSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const slidesService = ctx.google.slides({ version: 'v1', auth: ctx.authClient });\n const shapeProperties: any = {};\n const fields: string[] = [];\n\n if (a.backgroundColor) {\n shapeProperties.shapeBackgroundFill = {\n solidFill: {\n color: {\n rgbColor: {\n red: a.backgroundColor.red || 0,\n green: a.backgroundColor.green || 0,\n blue: a.backgroundColor.blue || 0\n }\n },\n alpha: a.backgroundColor.alpha || 1\n }\n };\n fields.push('shapeBackgroundFill');\n }\n\n const outline: any = {};\n let hasOutlineChanges = false;\n\n if (a.outlineColor) {\n outline.outlineFill = {\n solidFill: {\n color: {\n rgbColor: {\n red: a.outlineColor.red || 0,\n green: a.outlineColor.green || 0,\n blue: a.outlineColor.blue || 0\n }\n }\n }\n };\n hasOutlineChanges = true;\n }\n\n if (a.outlineWeight !== undefined) {\n outline.weight = {\n magnitude: a.outlineWeight,\n unit: 'PT'\n };\n hasOutlineChanges = true;\n }\n\n if (a.outlineDashStyle !== undefined) {\n outline.dashStyle = a.outlineDashStyle;\n hasOutlineChanges = true;\n }\n\n if (hasOutlineChanges) {\n shapeProperties.outline = outline;\n fields.push('outline');\n }\n\n if (fields.length === 0) {\n return errorResponse(\"No styling options specified\");\n }\n\n await slidesService.presentations.batchUpdate({\n presentationId: a.presentationId,\n requestBody: {\n requests: [{\n updateShapeProperties: {\n objectId: a.objectId,\n shapeProperties,\n fields: fields.join(',')\n }\n }]\n }\n });\n\n return {\n content: [{ type: \"text\", text: `Applied styling to shape ${a.objectId}` }],\n isError: false\n };\n }\n\n case \"setGoogleSlidesBackground\": {\n const validation = SetGoogleSlidesBackgroundSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const slidesService = ctx.google.slides({ version: 'v1', auth: ctx.authClient });\n const requests = a.pageObjectIds.map(pageObjectId => ({\n updatePageProperties: {\n objectId: pageObjectId,\n pageProperties: {\n pageBackgroundFill: {\n solidFill: {\n color: {\n rgbColor: {\n red: a.backgroundColor.red || 0,\n green: a.backgroundColor.green || 0,\n blue: a.backgroundColor.blue || 0\n }\n },\n alpha: a.backgroundColor.alpha || 1\n }\n }\n },\n fields: 'pageBackgroundFill'\n }\n }));\n\n await slidesService.presentations.batchUpdate({\n presentationId: a.presentationId,\n requestBody: { requests }\n });\n\n return {\n content: [{ type: \"text\", text: `Set background color for ${a.pageObjectIds.length} slide(s)` }],\n isError: false\n };\n }\n\n case \"createGoogleSlidesTextBox\": {\n const validation = CreateGoogleSlidesTextBoxSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const slidesService = ctx.google.slides({ version: 'v1', auth: ctx.authClient });\n const elementId = `textBox_${uuidv4().substring(0, 8)}`;\n\n const requests: any[] = [\n {\n createShape: {\n objectId: elementId,\n shapeType: 'TEXT_BOX',\n elementProperties: {\n pageObjectId: a.pageObjectId,\n size: {\n width: { magnitude: a.width, unit: 'EMU' },\n height: { magnitude: a.height, unit: 'EMU' }\n },\n transform: {\n scaleX: 1,\n scaleY: 1,\n translateX: a.x,\n translateY: a.y,\n unit: 'EMU'\n }\n }\n }\n },\n {\n insertText: {\n objectId: elementId,\n text: a.text,\n insertionIndex: 0\n }\n }\n ];\n\n // Apply optional formatting\n if (a.fontSize || a.bold || a.italic) {\n const textStyle: any = {};\n const fields: string[] = [];\n\n if (a.fontSize) {\n textStyle.fontSize = {\n magnitude: a.fontSize,\n unit: 'PT'\n };\n fields.push('fontSize');\n }\n\n if (a.bold !== undefined) {\n textStyle.bold = a.bold;\n fields.push('bold');\n }\n\n if (a.italic !== undefined) {\n textStyle.italic = a.italic;\n fields.push('italic');\n }\n\n if (fields.length > 0) {\n requests.push({\n updateTextStyle: {\n objectId: elementId,\n style: textStyle,\n fields: fields.join(','),\n textRange: { type: 'ALL' }\n }\n });\n }\n }\n\n await slidesService.presentations.batchUpdate({\n presentationId: a.presentationId,\n requestBody: { requests }\n });\n\n return {\n content: [{ type: \"text\", text: `Created text box with ID: ${elementId}` }],\n isError: false\n };\n }\n\n case \"createGoogleSlidesShape\": {\n const validation = CreateGoogleSlidesShapeSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const slidesService = ctx.google.slides({ version: 'v1', auth: ctx.authClient });\n const elementId = `shape_${uuidv4().substring(0, 8)}`;\n\n const createRequest: any = {\n createShape: {\n objectId: elementId,\n shapeType: a.shapeType,\n elementProperties: {\n pageObjectId: a.pageObjectId,\n size: {\n width: { magnitude: a.width, unit: 'EMU' },\n height: { magnitude: a.height, unit: 'EMU' }\n },\n transform: {\n scaleX: 1,\n scaleY: 1,\n translateX: a.x,\n translateY: a.y,\n unit: 'EMU'\n }\n }\n }\n };\n\n const requests = [createRequest];\n\n // Apply background color if specified\n if (a.backgroundColor) {\n requests.push({\n updateShapeProperties: {\n objectId: elementId,\n shapeProperties: {\n shapeBackgroundFill: {\n solidFill: {\n color: {\n rgbColor: {\n red: a.backgroundColor.red || 0,\n green: a.backgroundColor.green || 0,\n blue: a.backgroundColor.blue || 0\n }\n },\n alpha: a.backgroundColor.alpha || 1\n }\n }\n },\n fields: 'shapeBackgroundFill'\n }\n });\n }\n\n await slidesService.presentations.batchUpdate({\n presentationId: a.presentationId,\n requestBody: { requests }\n });\n\n return {\n content: [{ type: \"text\", text: `Created ${a.shapeType} shape with ID: ${elementId}` }],\n isError: false\n };\n }\n\n case \"getGoogleSlidesSpeakerNotes\": {\n const validation = GetGoogleSlidesSpeakerNotesSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const slidesService = ctx.google.slides({ version: 'v1', auth: ctx.authClient });\n\n // Get the presentation to access the slide\n const presentation = await slidesService.presentations.get({\n presentationId: a.presentationId\n });\n\n if (!presentation.data.slides || a.slideIndex >= presentation.data.slides.length) {\n return errorResponse(`Slide index ${a.slideIndex} not found in presentation (has ${presentation.data.slides?.length ?? 0} slides)`);\n }\n\n const slide = presentation.data.slides[a.slideIndex];\n\n // Get the notes page object ID from the slide properties\n const notesObjectId = slide.slideProperties?.notesPage?.notesProperties?.speakerNotesObjectId;\n\n if (!notesObjectId) {\n return {\n content: [{ type: \"text\", text: \"No speaker notes found for this slide\" }],\n isError: false\n };\n }\n\n // Get the notes page to read the speaker notes text\n const notesPageObjectId = slide.slideProperties?.notesPage?.objectId;\n if (!notesPageObjectId) {\n return {\n content: [{ type: \"text\", text: \"No speaker notes found for this slide\" }],\n isError: false\n };\n }\n\n // Find the notes page for this slide\n const notesPage = presentation.data.slides?.[a.slideIndex]?.slideProperties?.notesPage;\n\n if (!notesPage || !notesPage.pageElements) {\n return {\n content: [{ type: \"text\", text: \"No speaker notes found for this slide\" }],\n isError: false\n };\n }\n\n // Find the speaker notes shape\n const speakerNotesElement = notesPage.pageElements.find(\n element => element.objectId === notesObjectId\n );\n\n if (!speakerNotesElement || !speakerNotesElement.shape?.text) {\n return {\n content: [{ type: \"text\", text: \"No speaker notes found for this slide\" }],\n isError: false\n };\n }\n\n // Extract the text from the speaker notes\n let notesText = '';\n const textElements = speakerNotesElement.shape.text.textElements || [];\n textElements.forEach((textElement) => {\n if (textElement.textRun?.content) {\n notesText += textElement.textRun.content;\n }\n });\n\n return {\n content: [{ type: \"text\", text: notesText.trim() || \"No speaker notes found for this slide\" }],\n isError: false\n };\n }\n\n case \"updateGoogleSlidesSpeakerNotes\": {\n const validation = UpdateGoogleSlidesSpeakerNotesSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const slidesService = ctx.google.slides({ version: 'v1', auth: ctx.authClient });\n\n // Get the presentation to access the slide\n const presentation = await slidesService.presentations.get({\n presentationId: a.presentationId\n });\n\n if (!presentation.data.slides || a.slideIndex >= presentation.data.slides.length) {\n return errorResponse(`Slide index ${a.slideIndex} not found in presentation (has ${presentation.data.slides?.length ?? 0} slides)`);\n }\n\n const slide = presentation.data.slides[a.slideIndex];\n\n // Get the notes page object ID from the slide properties\n const notesObjectId = slide.slideProperties?.notesPage?.notesProperties?.speakerNotesObjectId;\n\n if (!notesObjectId) {\n return errorResponse(\"This slide does not have a speaker notes object. Speaker notes may need to be initialized manually in Google Slides first.\");\n }\n\n // Create the batchUpdate request to replace the speaker notes text\n // Only delete existing text if there is any \u2014 deleteText with type:'ALL' fails on empty notes\n const notesPage = slide.slideProperties?.notesPage;\n const speakerNotesShape = notesPage?.pageElements?.find(\n (el: any) => el.objectId === notesObjectId\n );\n const existingTextElements = speakerNotesShape?.shape?.text?.textElements || [];\n const hasExistingText = existingTextElements.some(\n (el: any) => el.textRun?.content\n );\n\n const requests: any[] = [];\n\n if (hasExistingText) {\n requests.push({ deleteText: { objectId: notesObjectId, textRange: { type: 'ALL' } } });\n }\n\n requests.push({ insertText: { objectId: notesObjectId, text: a.notes, insertionIndex: 0 } });\n\n await slidesService.presentations.batchUpdate({\n presentationId: a.presentationId,\n requestBody: { requests }\n });\n\n return {\n content: [{ type: \"text\", text: `Successfully updated speaker notes for slide ${a.slideIndex}` }],\n isError: false\n };\n }\n\n case \"deleteGoogleSlide\": {\n const validation = DeleteGoogleSlideSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const a = validation.data;\n\n const slidesService = ctx.google.slides({ version: 'v1', auth: ctx.authClient });\n await slidesService.presentations.batchUpdate({\n presentationId: a.presentationId,\n requestBody: {\n requests: [{ deleteObject: { objectId: a.slideObjectId } }]\n }\n });\n\n return {\n content: [{ type: 'text', text: `Deleted slide ${a.slideObjectId}` }],\n isError: false,\n };\n }\n\n case \"duplicateSlide\": {\n const validation = DuplicateSlideSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const a = validation.data;\n\n const slidesService = ctx.google.slides({ version: 'v1', auth: ctx.authClient });\n const response = await slidesService.presentations.batchUpdate({\n presentationId: a.presentationId,\n requestBody: {\n requests: [{ duplicateObject: { objectId: a.slideObjectId } }]\n }\n });\n\n const dupId = response.data.replies?.[0]?.duplicateObject?.objectId;\n return {\n content: [{ type: 'text', text: `Duplicated slide ${a.slideObjectId}${dupId ? ` -> ${dupId}` : ''}` }],\n isError: false,\n };\n }\n\n case \"reorderSlides\": {\n const validation = ReorderSlidesSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const a = validation.data;\n\n const slidesService = ctx.google.slides({ version: 'v1', auth: ctx.authClient });\n await slidesService.presentations.batchUpdate({\n presentationId: a.presentationId,\n requestBody: {\n requests: [{\n updateSlidesPosition: {\n slideObjectIds: a.slideObjectIds,\n insertionIndex: a.insertionIndex,\n }\n }]\n }\n });\n\n return {\n content: [{ type: 'text', text: `Reordered ${a.slideObjectIds.length} slide(s) to index ${a.insertionIndex}` }],\n isError: false,\n };\n }\n\n case \"replaceAllTextInSlides\": {\n const validation = ReplaceAllTextInSlidesSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const a = validation.data;\n\n const slidesService = ctx.google.slides({ version: 'v1', auth: ctx.authClient });\n const response = await slidesService.presentations.batchUpdate({\n presentationId: a.presentationId,\n requestBody: {\n requests: [{\n replaceAllText: {\n containsText: {\n text: a.containsText,\n matchCase: a.matchCase,\n },\n replaceText: a.replaceText,\n }\n }]\n }\n });\n\n const count = response.data.replies?.[0]?.replaceAllText?.occurrencesChanged ?? 0;\n return {\n content: [{ type: 'text', text: `Replaced ${count} occurrence(s) of \"${a.containsText}\" in slides.` }],\n isError: false,\n };\n }\n\n case \"exportSlideThumbnail\": {\n const validation = ExportSlideThumbnailSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const a = validation.data;\n\n const slidesService = ctx.google.slides({ version: 'v1', auth: ctx.authClient });\n const response = await slidesService.presentations.pages.getThumbnail({\n presentationId: a.presentationId,\n pageObjectId: a.slideObjectId,\n 'thumbnailProperties.mimeType': a.mimeType,\n 'thumbnailProperties.thumbnailSize': a.size,\n });\n\n const url = response.data?.contentUrl;\n if (!url) return errorResponse('No thumbnail URL returned by Google Slides API.');\n\n return {\n content: [{ type: 'text', text: `Slide thumbnail URL (${a.mimeType}, ${a.size}): ${url}` }],\n isError: false,\n };\n }\n\n case \"getSlideElementInfo\": {\n const validation = GetSlideElementInfoSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const a = validation.data;\n\n const slidesService = ctx.google.slides({ version: 'v1', auth: ctx.authClient });\n\n // Page size lives on the presentation; grab just that field.\n const sizeOnly = await slidesService.presentations.get({\n presentationId: a.presentationId,\n fields: 'pageSize',\n });\n const slideWidth = sizeOnly.data.pageSize?.width?.magnitude || 9144000;\n const slideHeight = sizeOnly.data.pageSize?.height?.magnitude || 6858000;\n\n // If a specific slide is requested, fetch just that page. Otherwise fetch\n // only the fields of the slides we actually render.\n let slides: slides_v1.Schema$Page[] = [];\n if (a.slideObjectId) {\n const page = await slidesService.presentations.pages.get({\n presentationId: a.presentationId,\n pageObjectId: a.slideObjectId,\n fields: 'objectId,pageElements(objectId,transform,size,shape/shapeType,image)',\n });\n slides = [page.data];\n } else {\n const withSlides = await slidesService.presentations.get({\n presentationId: a.presentationId,\n fields: 'slides(objectId,pageElements(objectId,transform,size,shape/shapeType,image))',\n });\n slides = withSlides.data.slides || [];\n }\n\n const lines: string[] = [`Slide dimensions: ${slideWidth} x ${slideHeight} EMU`];\n for (const slide of slides) {\n lines.push(`\\n--- Slide: ${slide.objectId} ---`);\n for (const el of slide.pageElements || []) {\n const t = el.transform || {};\n const s = el.size || {};\n const intrW = s.width?.magnitude || 0;\n const intrH = s.height?.magnitude || 0;\n const scX = t.scaleX || 1;\n const scY = t.scaleY || 1;\n const tx = t.translateX || 0;\n const ty = t.translateY || 0;\n const renderedW = intrW * scX;\n const renderedH = intrH * scY;\n const right = tx + renderedW;\n const bottom = ty + renderedH;\n const offPage = (tx < 0 || ty < 0 || right > slideWidth || bottom > slideHeight)\n ? ' *** OFF PAGE ***' : '';\n lines.push(` ${el.objectId} (${el.shape ? 'shape:' + el.shape.shapeType : el.image ? 'image' : 'other'})`);\n lines.push(` intrinsic: ${intrW} x ${intrH}, scale: ${scX} x ${scY}`);\n lines.push(` rendered: ${Math.round(renderedW)} x ${Math.round(renderedH)} at (${tx}, ${ty})`);\n lines.push(` bounds: right=${Math.round(right)}, bottom=${Math.round(bottom)}${offPage}`);\n }\n }\n\n return { content: [{ type: 'text', text: lines.join('\\n') }], isError: false };\n }\n\n case \"moveSlideElement\": {\n const validation = MoveSlideElementSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const a = validation.data;\n\n const slidesService = ctx.google.slides({ version: 'v1', auth: ctx.authClient });\n\n // Field-masked fetch: we only need each element's objectId/transform/size.\n const pres = await slidesService.presentations.get({\n presentationId: a.presentationId,\n fields: 'slides(pageElements(objectId,transform,size))',\n });\n\n let currentTransform: slides_v1.Schema$AffineTransform | null = null;\n let currentSize: slides_v1.Schema$Size | null = null;\n for (const slide of pres.data.slides || []) {\n for (const el of slide.pageElements || []) {\n if (el.objectId === a.objectId) {\n currentTransform = el.transform || null;\n currentSize = el.size || null;\n break;\n }\n }\n if (currentTransform) break;\n }\n\n if (!currentTransform) {\n return errorResponse(`Element ${a.objectId} not found in presentation`);\n }\n\n const origWidth = currentSize?.width?.magnitude || 3000000;\n const origHeight = currentSize?.height?.magnitude || 3000000;\n const curScaleX = currentTransform.scaleX || 1;\n const curScaleY = currentTransform.scaleY || 1;\n\n const newScaleX = a.width !== undefined ? a.width / origWidth : curScaleX;\n const newScaleY = a.height !== undefined ? a.height / origHeight : curScaleY;\n const newX = a.x ?? (currentTransform.translateX || 0);\n const newY = a.y ?? (currentTransform.translateY || 0);\n\n const newTransform: slides_v1.Schema$AffineTransform = {\n scaleX: newScaleX,\n scaleY: newScaleY,\n translateX: newX,\n translateY: newY,\n shearX: currentTransform.shearX || 0,\n shearY: currentTransform.shearY || 0,\n unit: 'EMU',\n };\n\n const requests: slides_v1.Schema$Request[] = [{\n updatePageElementTransform: {\n objectId: a.objectId,\n applyMode: 'ABSOLUTE',\n transform: newTransform,\n },\n }];\n\n await slidesService.presentations.batchUpdate({\n presentationId: a.presentationId,\n requestBody: { requests },\n });\n\n const didResize = a.width !== undefined || a.height !== undefined;\n const action = didResize ? 'Moved/resized' : 'Moved';\n return {\n content: [{ type: 'text', text: `${action} element ${a.objectId} to (${newX}, ${newY})` }],\n isError: false,\n };\n }\n\n case \"deleteSlideElement\": {\n const validation = DeleteSlideElementSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const a = validation.data;\n\n const slidesService = ctx.google.slides({ version: 'v1', auth: ctx.authClient });\n await slidesService.presentations.batchUpdate({\n presentationId: a.presentationId,\n requestBody: {\n requests: [{ deleteObject: { objectId: a.objectId } }],\n },\n });\n\n return {\n content: [{ type: 'text', text: `Deleted element ${a.objectId}` }],\n isError: false,\n };\n }\n\n case \"insertSlidesImageFromUrl\": {\n const validation = InsertSlidesImageFromUrlSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const a = validation.data;\n return insertImageIntoSlide(ctx, a.presentationId, a.pageObjectId, a.imageUrl, a.x, a.y, a.width, a.height);\n }\n\n case \"insertSlidesLocalImage\": {\n const validation = InsertSlidesLocalImageSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const a = validation.data;\n\n // Upload briefly as public so the Slides API can fetch the bytes.\n const { fileId, webContentLink } = await uploadImageToDrive(ctx, a.localImagePath, {\n makePublic: true,\n });\n try {\n const result = await insertImageIntoSlide(\n ctx, a.presentationId, a.pageObjectId, webContentLink,\n a.x, a.y, a.width, a.height,\n );\n // Slides stores its own copy once createImage returns, so the intermediary\n // Drive file is no longer referenced. Delete it (which also removes the\n // public permission we just granted).\n await deleteDriveFile(ctx, fileId).catch((err) =>\n ctx.log(`insertSlidesLocalImage: failed to delete intermediary Drive file ${fileId}`, err),\n );\n return result;\n } catch (err) {\n // On embed failure, still try to clean up the uploaded file.\n await deleteDriveFile(ctx, fileId).catch(() => {});\n throw err;\n }\n }\n\n default:\n return null;\n }\n}\n", "import { z } from 'zod';\nimport { buildCalendarEventUpdate } from '../utils.js';\nimport { errorResponse } from '../types.js';\nimport type { ToolDefinition, ToolResult, ToolContext } from '../types.js';\n\n// ---------------------------------------------------------------------------\n// Interfaces\n// ---------------------------------------------------------------------------\n\ninterface CalendarEventInfo {\n id: string;\n summary?: string;\n description?: string;\n location?: string;\n start?: { dateTime?: string; date?: string; timeZone?: string };\n end?: { dateTime?: string; date?: string; timeZone?: string };\n status?: string;\n htmlLink?: string;\n hangoutLink?: string;\n meetingLink?: string;\n attendees?: { email: string; displayName?: string; responseStatus?: string }[];\n organizer?: { email?: string; displayName?: string };\n recurrence?: string[];\n created?: string;\n updated?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction formatCalendarEvent(event: any): CalendarEventInfo {\n const result: CalendarEventInfo = {\n id: event.id || '',\n summary: event.summary,\n description: event.description,\n location: event.location,\n status: event.status,\n htmlLink: event.htmlLink,\n created: event.created,\n updated: event.updated,\n };\n\n if (event.start) {\n result.start = {\n dateTime: event.start.dateTime,\n date: event.start.date,\n timeZone: event.start.timeZone,\n };\n }\n\n if (event.end) {\n result.end = {\n dateTime: event.end.dateTime,\n date: event.end.date,\n timeZone: event.end.timeZone,\n };\n }\n\n if (event.hangoutLink) {\n result.hangoutLink = event.hangoutLink;\n }\n\n if (event.conferenceData?.entryPoints) {\n const videoEntry = event.conferenceData.entryPoints.find((ep: any) => ep.entryPointType === 'video');\n if (videoEntry?.uri) {\n result.meetingLink = videoEntry.uri;\n }\n }\n\n if (event.attendees) {\n result.attendees = event.attendees.map((a: any) => ({\n email: a.email || '',\n displayName: a.displayName,\n responseStatus: a.responseStatus,\n }));\n }\n\n if (event.organizer) {\n result.organizer = {\n email: event.organizer.email,\n displayName: event.organizer.displayName,\n };\n }\n\n if (event.recurrence) {\n result.recurrence = event.recurrence;\n }\n\n return result;\n}\n\nfunction formatEventForDisplay(event: CalendarEventInfo): string {\n const lines: string[] = [];\n lines.push(`**${event.summary || '(No title)'}**`);\n\n if (event.start) {\n const startStr = event.start.dateTime || event.start.date || '';\n const endStr = event.end?.dateTime || event.end?.date || '';\n if (event.start.date) {\n // All-day event\n lines.push(`Date: ${startStr}${endStr && endStr !== startStr ? ` - ${endStr}` : ''}`);\n } else {\n lines.push(`Time: ${startStr} - ${endStr}`);\n }\n }\n\n if (event.location) lines.push(`Location: ${event.location}`);\n if (event.description) lines.push(`Description: ${event.description}`);\n if (event.hangoutLink || event.meetingLink) {\n lines.push(`Meeting: ${event.meetingLink || event.hangoutLink}`);\n }\n if (event.attendees && event.attendees.length > 0) {\n lines.push(`Attendees: ${event.attendees.map(a => a.email).join(', ')}`);\n }\n if (event.htmlLink) lines.push(`Link: ${event.htmlLink}`);\n lines.push(`Event ID: ${event.id}`);\n\n return lines.join('\\n');\n}\n\n// ---------------------------------------------------------------------------\n// Zod Schemas\n// ---------------------------------------------------------------------------\n\nconst ListCalendarsSchema = z.object({\n showHidden: z.boolean().optional().default(false).describe(\"Include hidden calendars\")\n});\n\nconst GetCalendarEventsSchema = z.object({\n calendarId: z.string().optional().default(\"primary\").describe(\"Calendar ID (default: primary)\"),\n timeMin: z.string().optional().describe(\"Start of time range (RFC3339, e.g., '2024-01-01T00:00:00Z')\"),\n timeMax: z.string().optional().describe(\"End of time range (RFC3339)\"),\n query: z.string().optional().describe(\"Free text search in events\"),\n maxResults: z.number().int().min(1).max(250).optional().default(50).describe(\"Maximum events to return (1-250)\"),\n singleEvents: z.boolean().optional().default(true).describe(\"Expand recurring events into instances\"),\n orderBy: z.enum([\"startTime\", \"updated\"]).optional().default(\"startTime\").describe(\"Sort order\")\n});\n\nconst GetCalendarEventSchema = z.object({\n eventId: z.string().min(1, \"Event ID is required\"),\n calendarId: z.string().optional().default(\"primary\").describe(\"Calendar ID (default: primary)\")\n});\n\nconst CreateCalendarEventSchema = z.object({\n summary: z.string().min(1, \"Event title is required\"),\n calendarId: z.string().optional().default(\"primary\").describe(\"Calendar ID (default: primary)\"),\n description: z.string().optional().describe(\"Event description\"),\n location: z.string().optional().describe(\"Event location\"),\n start: z.object({\n dateTime: z.string().optional().describe(\"RFC3339 timestamp for timed events\"),\n date: z.string().optional().describe(\"Date for all-day events (YYYY-MM-DD)\"),\n timeZone: z.string().optional().describe(\"Time zone (e.g., 'America/Los_Angeles')\")\n }).describe(\"Start time\"),\n end: z.object({\n dateTime: z.string().optional().describe(\"RFC3339 timestamp for timed events\"),\n date: z.string().optional().describe(\"Date for all-day events (YYYY-MM-DD)\"),\n timeZone: z.string().optional().describe(\"Time zone (e.g., 'America/Los_Angeles')\")\n }).describe(\"End time\"),\n attendees: z.array(z.string()).optional().describe(\"Email addresses of attendees\"),\n sendUpdates: z.enum([\"all\", \"externalOnly\", \"none\"]).optional().default(\"none\").describe(\"Send notifications to attendees (default: none)\"),\n conferenceType: z.enum([\"hangoutsMeet\"]).optional().describe(\"Add Google Meet link\"),\n recurrence: z.array(z.string()).optional().describe(\"RRULE strings for recurring events\"),\n visibility: z.enum([\"default\", \"public\", \"private\", \"confidential\"]).optional().describe(\"Event visibility\")\n});\n\nconst UpdateCalendarEventSchema = z.object({\n eventId: z.string().min(1, \"Event ID is required\"),\n calendarId: z.string().optional().default(\"primary\").describe(\"Calendar ID (default: primary)\"),\n summary: z.string().optional().describe(\"New event title\"),\n description: z.string().optional().describe(\"New event description\"),\n location: z.string().optional().describe(\"New event location\"),\n start: z.object({\n dateTime: z.string().optional(),\n date: z.string().optional(),\n timeZone: z.string().optional()\n }).optional().describe(\"New start time\"),\n end: z.object({\n dateTime: z.string().optional(),\n date: z.string().optional(),\n timeZone: z.string().optional()\n }).optional().describe(\"New end time\"),\n attendees: z.array(z.string()).optional().describe(\"Updated attendee emails (replaces existing)\"),\n sendUpdates: z.enum([\"all\", \"externalOnly\", \"none\"]).optional().default(\"none\").describe(\"Send notifications about the update (default: none)\")\n});\n\nconst DeleteCalendarEventSchema = z.object({\n eventId: z.string().min(1, \"Event ID is required\"),\n calendarId: z.string().optional().default(\"primary\").describe(\"Calendar ID (default: primary)\"),\n sendUpdates: z.enum([\"all\", \"externalOnly\", \"none\"]).optional().default(\"none\").describe(\"Send cancellation notifications to attendees (default: none)\")\n});\n\n// ---------------------------------------------------------------------------\n// Tool Definitions\n// ---------------------------------------------------------------------------\n\nexport const toolDefinitions: ToolDefinition[] = [\n {\n name: \"listCalendars\",\n description: \"List all accessible Google Calendars for the authenticated user\",\n inputSchema: {\n type: \"object\",\n properties: {\n showHidden: { type: \"boolean\", description: \"Include hidden calendars (default: false)\" }\n }\n }\n },\n {\n name: \"getCalendarEvents\",\n description: \"Get events from a Google Calendar with optional filtering\",\n inputSchema: {\n type: \"object\",\n properties: {\n calendarId: { type: \"string\", description: \"Calendar ID (default: primary)\" },\n timeMin: { type: \"string\", description: \"Start of time range (RFC3339, e.g., '2024-01-01T00:00:00Z')\" },\n timeMax: { type: \"string\", description: \"End of time range (RFC3339)\" },\n query: { type: \"string\", description: \"Free text search in events\" },\n maxResults: { type: \"number\", description: \"Maximum events to return (1-250, default: 50)\" },\n singleEvents: { type: \"boolean\", description: \"Expand recurring events into instances (default: true)\" },\n orderBy: { type: \"string\", enum: [\"startTime\", \"updated\"], description: \"Sort order (default: startTime)\" }\n }\n }\n },\n {\n name: \"getCalendarEvent\",\n description: \"Get a single calendar event by ID\",\n inputSchema: {\n type: \"object\",\n properties: {\n eventId: { type: \"string\", description: \"The event ID to retrieve\" },\n calendarId: { type: \"string\", description: \"Calendar ID (default: primary)\" }\n },\n required: [\"eventId\"]\n }\n },\n {\n name: \"createCalendarEvent\",\n description: \"Create a new calendar event. Supports timed events, all-day events, and Google Meet integration.\",\n inputSchema: {\n type: \"object\",\n properties: {\n summary: { type: \"string\", description: \"Event title\" },\n calendarId: { type: \"string\", description: \"Calendar ID (default: primary)\" },\n description: { type: \"string\", description: \"Event description\" },\n location: { type: \"string\", description: \"Event location\" },\n start: {\n type: \"object\",\n description: \"Start time (use dateTime for timed events, date for all-day)\",\n properties: {\n dateTime: { type: \"string\", description: \"RFC3339 timestamp (e.g., '2024-01-15T09:00:00-08:00')\" },\n date: { type: \"string\", description: \"Date for all-day events (YYYY-MM-DD)\" },\n timeZone: { type: \"string\", description: \"Time zone (e.g., 'America/Los_Angeles')\" }\n }\n },\n end: {\n type: \"object\",\n description: \"End time\",\n properties: {\n dateTime: { type: \"string\" },\n date: { type: \"string\" },\n timeZone: { type: \"string\" }\n }\n },\n attendees: { type: \"array\", items: { type: \"string\" }, description: \"Email addresses of attendees\" },\n sendUpdates: { type: \"string\", enum: [\"all\", \"externalOnly\", \"none\"], description: \"Send notifications (default: none)\" },\n conferenceType: { type: \"string\", enum: [\"hangoutsMeet\"], description: \"Add Google Meet link\" },\n recurrence: { type: \"array\", items: { type: \"string\" }, description: \"RRULE strings for recurring events\" },\n visibility: { type: \"string\", enum: [\"default\", \"public\", \"private\", \"confidential\"], description: \"Event visibility\" }\n },\n required: [\"summary\", \"start\", \"end\"]\n }\n },\n {\n name: \"updateCalendarEvent\",\n description: \"Update an existing calendar event\",\n inputSchema: {\n type: \"object\",\n properties: {\n eventId: { type: \"string\", description: \"The event ID to update\" },\n calendarId: { type: \"string\", description: \"Calendar ID (default: primary)\" },\n summary: { type: \"string\", description: \"New event title\" },\n description: { type: \"string\", description: \"New event description\" },\n location: { type: \"string\", description: \"New event location\" },\n start: {\n type: \"object\",\n properties: {\n dateTime: { type: \"string\" },\n date: { type: \"string\" },\n timeZone: { type: \"string\" }\n }\n },\n end: {\n type: \"object\",\n properties: {\n dateTime: { type: \"string\" },\n date: { type: \"string\" },\n timeZone: { type: \"string\" }\n }\n },\n attendees: { type: \"array\", items: { type: \"string\" }, description: \"Updated attendee emails (replaces existing)\" },\n sendUpdates: { type: \"string\", enum: [\"all\", \"externalOnly\", \"none\"], description: \"Send notifications (default: none)\" }\n },\n required: [\"eventId\"]\n }\n },\n {\n name: \"deleteCalendarEvent\",\n description: \"Delete a calendar event\",\n inputSchema: {\n type: \"object\",\n properties: {\n eventId: { type: \"string\", description: \"The event ID to delete\" },\n calendarId: { type: \"string\", description: \"Calendar ID (default: primary)\" },\n sendUpdates: { type: \"string\", enum: [\"all\", \"externalOnly\", \"none\"], description: \"Send cancellation notifications (default: none)\" }\n },\n required: [\"eventId\"]\n }\n }\n];\n\n// ---------------------------------------------------------------------------\n// Handler\n// ---------------------------------------------------------------------------\n\nexport async function handleTool(\n toolName: string,\n args: Record<string, unknown>,\n ctx: ToolContext,\n): Promise<ToolResult | null> {\n switch (toolName) {\n case \"listCalendars\": {\n const validation = ListCalendarsSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const parsed = validation.data;\n\n const response = await ctx.getCalendar().calendarList.list({\n showHidden: parsed.showHidden,\n maxResults: 250\n });\n\n const calendars = response.data.items || [];\n if (calendars.length === 0) {\n return { content: [{ type: \"text\", text: \"No calendars found.\" }], isError: false };\n }\n\n const lines = calendars.map((cal: any) => {\n const primary = cal.primary ? ' (PRIMARY)' : '';\n const role = cal.accessRole ? ` [${cal.accessRole}]` : '';\n return `- ${cal.summary}${primary}${role}\\n ID: ${cal.id}`;\n });\n\n return {\n content: [{ type: \"text\", text: `Found ${calendars.length} calendar(s):\\n\\n${lines.join('\\n\\n')}` }],\n isError: false\n };\n }\n\n case \"getCalendarEvents\": {\n const validation = GetCalendarEventsSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const parsed = validation.data;\n\n const params: any = {\n calendarId: parsed.calendarId || 'primary',\n maxResults: parsed.maxResults || 50,\n singleEvents: parsed.singleEvents !== false,\n orderBy: parsed.orderBy || 'startTime'\n };\n\n if (parsed.timeMin) params.timeMin = parsed.timeMin;\n if (parsed.timeMax) params.timeMax = parsed.timeMax;\n if (parsed.query) params.q = parsed.query;\n\n const response = await ctx.getCalendar().events.list(params);\n\n const events = response.data.items || [];\n if (events.length === 0) {\n return { content: [{ type: \"text\", text: \"No events found.\" }], isError: false };\n }\n\n const formattedEvents = events.map((e: any) => formatEventForDisplay(formatCalendarEvent(e)));\n\n return {\n content: [{ type: \"text\", text: `Found ${events.length} event(s):\\n\\n${formattedEvents.join('\\n\\n---\\n\\n')}` }],\n isError: false\n };\n }\n\n case \"getCalendarEvent\": {\n const validation = GetCalendarEventSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const parsed = validation.data;\n\n const response = await ctx.getCalendar().events.get({\n calendarId: parsed.calendarId || 'primary',\n eventId: parsed.eventId\n });\n\n const formatted = formatEventForDisplay(formatCalendarEvent(response.data));\n return {\n content: [{ type: \"text\", text: formatted }],\n isError: false\n };\n }\n\n case \"createCalendarEvent\": {\n const validation = CreateCalendarEventSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const parsed = validation.data;\n\n const eventResource: any = {\n summary: parsed.summary,\n description: parsed.description,\n location: parsed.location,\n start: parsed.start,\n end: parsed.end,\n visibility: parsed.visibility\n };\n\n if (parsed.attendees && parsed.attendees.length > 0) {\n eventResource.attendees = parsed.attendees.map((email: string) => ({ email }));\n }\n\n if (parsed.recurrence) {\n eventResource.recurrence = parsed.recurrence;\n }\n\n let conferenceDataVersion = 0;\n if (parsed.conferenceType === 'hangoutsMeet') {\n eventResource.conferenceData = {\n createRequest: {\n requestId: `meet-${Date.now()}`,\n conferenceSolutionKey: { type: 'hangoutsMeet' }\n }\n };\n conferenceDataVersion = 1;\n }\n\n const insertParams: any = {\n calendarId: parsed.calendarId || 'primary',\n requestBody: eventResource,\n sendUpdates: parsed.sendUpdates\n };\n\n if (conferenceDataVersion > 0) {\n insertParams.conferenceDataVersion = conferenceDataVersion;\n }\n\n const response = await ctx.getCalendar().events.insert(insertParams);\n const created = formatCalendarEvent(response.data);\n\n return {\n content: [{ type: \"text\", text: `Event created successfully!\\n\\n${formatEventForDisplay(created)}` }],\n isError: false\n };\n }\n\n case \"updateCalendarEvent\": {\n const validation = UpdateCalendarEventSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const parsed = validation.data;\n\n // First get the existing event\n const existingResponse = await ctx.getCalendar().events.get({\n calendarId: parsed.calendarId || 'primary',\n eventId: parsed.eventId\n });\n\n const existing = existingResponse.data;\n const eventResource = buildCalendarEventUpdate(existing, parsed);\n\n const response = await ctx.getCalendar().events.update({\n calendarId: parsed.calendarId || 'primary',\n eventId: parsed.eventId,\n requestBody: eventResource,\n sendUpdates: parsed.sendUpdates\n });\n\n const updated = formatCalendarEvent(response.data);\n\n return {\n content: [{ type: \"text\", text: `Event updated successfully!\\n\\n${formatEventForDisplay(updated)}` }],\n isError: false\n };\n }\n\n case \"deleteCalendarEvent\": {\n const validation = DeleteCalendarEventSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const parsed = validation.data;\n\n await ctx.getCalendar().events.delete({\n calendarId: parsed.calendarId || 'primary',\n eventId: parsed.eventId,\n sendUpdates: parsed.sendUpdates\n });\n\n return {\n content: [{ type: \"text\", text: `Event ${parsed.eventId} has been deleted.` }],\n isError: false\n };\n }\n\n default:\n return null;\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["__dirname", "OAuth2Client", "fs", "path", "OAuth2Client", "resolve", "OAuth2Client", "OAuth2Client", "resolve", "fileURLToPath", "join", "dirname", "existsSync", "statSync", "readFile", "writeFile", "basename", "extname", "join", "dirname", "join", "resolve", "log", "readFile", "join", "writeFile", "resolveParentPath", "existsSync", "statSync", "basename", "extname", "handleTool", "toolDefinitions", "z", "existsSync", "createReadStream", "basename", "extname", "z", "toolDefinitions", "handleTool", "resolveInlineElementText", "extractSegments", "formatSegments", "hasFormattingInfo", "buildMetaLine", "trackFonts", "a", "extractText", "getContext", "handleTool", "toolDefinitions", "z", "z", "toolDefinitions", "handleTool", "handleTool", "toolDefinitions", "z", "z", "toolDefinitions", "handleTool", "handleTool", "toolDefinitions", "z", "z", "toolDefinitions", "handleTool", "FOLDER_MIME_TYPE", "fileURLToPath", "dirname", "join", "sid"]
|
|
4
|
+
"sourcesContent": ["#!/usr/bin/env node\n\nimport { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { StreamableHTTPServerTransport } from \"@modelcontextprotocol/sdk/server/streamableHttp.js\";\nimport { createMcpExpressApp } from \"@modelcontextprotocol/sdk/server/express.js\";\nimport {\n CallToolRequestSchema,\n ListResourcesRequestSchema,\n ListToolsRequestSchema,\n ReadResourceRequestSchema,\n isInitializeRequest,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { randomUUID } from 'crypto';\nimport { google } from \"googleapis\";\nimport type { drive_v3, calendar_v3 } from \"googleapis\";\nimport { authenticate, AuthServer, initializeOAuth2Client } from './auth.js';\nimport { fileURLToPath } from 'url';\nimport { readFileSync } from 'fs';\nimport { join, dirname } from 'path';\nimport {\n getExtensionFromFilename,\n escapeDriveQuery,\n} from './utils.js';\nimport type { ToolContext } from './types.js';\nimport { errorResponse } from './types.js';\n\nimport * as driveTools from './tools/drive.js';\nimport * as docsTools from './tools/docs.js';\nimport * as sheetsTools from './tools/sheets.js';\nimport * as slidesTools from './tools/slides.js';\nimport * as calendarTools from './tools/calendar.js';\n\n// Cached service instances \u2014 only recreated when authClient changes\nlet _drive: drive_v3.Drive | null = null;\nlet _calendar: calendar_v3.Calendar | null = null;\nlet _lastAuthClient: any = null;\n\nfunction getDrive(): drive_v3.Drive {\n if (!authClient) throw new Error('Authentication required');\n if (_drive && _lastAuthClient === authClient) return _drive;\n _drive = google.drive({ version: 'v3', auth: authClient });\n log('Drive service created');\n return _drive;\n}\n\nfunction getCalendar(): calendar_v3.Calendar {\n if (!authClient) throw new Error('Authentication required');\n if (_calendar && _lastAuthClient === authClient) return _calendar;\n _calendar = google.calendar({ version: 'v3', auth: authClient });\n log('Calendar service created');\n return _calendar;\n}\n\nconst FOLDER_MIME_TYPE = 'application/vnd.google-apps.folder';\n\n// Global auth client - will be initialized on first use\nlet authClient: any = null;\nlet authenticationPromise: Promise<any> | null = null;\n\n// Get package version\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst packageJsonPath = join(__dirname, '..', 'package.json');\nconst packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\nconst VERSION = packageJson.version;\n\n// -----------------------------------------------------------------------------\n// LOGGING UTILITY\n// -----------------------------------------------------------------------------\nfunction log(message: string, data?: any) {\n const timestamp = new Date().toISOString();\n const logMessage = data\n ? `[${timestamp}] ${message}: ${JSON.stringify(data)}`\n : `[${timestamp}] ${message}`;\n console.error(logMessage);\n}\n\n// -----------------------------------------------------------------------------\n// HELPER FUNCTIONS\n// -----------------------------------------------------------------------------\n\nasync function resolvePath(pathStr: string): Promise<string> {\n if (!pathStr || pathStr === '/') return 'root';\n\n const parts = pathStr.replace(/^\\/+|\\/+$/g, '').split('/');\n let currentFolderId: string = 'root';\n\n for (const part of parts) {\n if (!part) continue;\n const escapedPart = escapeDriveQuery(part);\n const response = await getDrive().files.list({\n q: `'${currentFolderId}' in parents and name = '${escapedPart}' and mimeType = '${FOLDER_MIME_TYPE}' and trashed = false`,\n fields: 'files(id)',\n spaces: 'drive',\n includeItemsFromAllDrives: true,\n supportsAllDrives: true\n });\n\n if (!response.data.files?.length) {\n const folderMetadata = {\n name: part,\n mimeType: FOLDER_MIME_TYPE,\n parents: [currentFolderId]\n };\n const folder = await getDrive().files.create({\n requestBody: folderMetadata,\n fields: 'id',\n supportsAllDrives: true\n });\n\n if (!folder.data.id) {\n throw new Error(`Failed to create intermediate folder: ${part}`);\n }\n\n currentFolderId = folder.data.id;\n } else {\n currentFolderId = response.data.files[0].id!;\n }\n }\n\n return currentFolderId;\n}\n\nasync function resolveFolderId(input: string | undefined): Promise<string> {\n if (!input) return 'root';\n\n if (input.startsWith('/')) {\n return resolvePath(input);\n } else {\n return input;\n }\n}\n\nfunction validateTextFileExtension(name: string) {\n const ext = getExtensionFromFilename(name);\n if (!['txt', 'md'].includes(ext)) {\n throw new Error(\"File name must end with .txt or .md for text files.\");\n }\n}\n\nasync function checkFileExists(name: string, parentFolderId: string = 'root'): Promise<string | null> {\n try {\n const escapedName = escapeDriveQuery(name);\n const query = `name = '${escapedName}' and '${parentFolderId}' in parents and trashed = false`;\n\n const res = await getDrive().files.list({\n q: query,\n fields: 'files(id, name, mimeType)',\n pageSize: 1,\n includeItemsFromAllDrives: true,\n supportsAllDrives: true\n });\n\n if (res.data.files && res.data.files.length > 0) {\n return res.data.files[0].id || null;\n }\n return null;\n } catch (error) {\n log('Error checking file existence:', error);\n return null;\n }\n}\n\n// -----------------------------------------------------------------------------\n// AUTHENTICATION HELPER\n// -----------------------------------------------------------------------------\nasync function ensureAuthenticated() {\n if (authClient) return;\n\n if (authenticationPromise) {\n log('Authentication already in progress, waiting...');\n authClient = await authenticationPromise;\n return;\n }\n\n log('Initializing authentication');\n authenticationPromise = authenticate();\n try {\n authClient = await authenticationPromise;\n log('Authentication complete');\n } finally {\n authenticationPromise = null;\n }\n}\n\n// -----------------------------------------------------------------------------\n// DOMAIN MODULES\n// -----------------------------------------------------------------------------\nconst domainModules = [driveTools, docsTools, sheetsTools, slidesTools, calendarTools];\n\nfunction buildToolContext(): ToolContext {\n return {\n authClient,\n google,\n getDrive,\n getCalendar,\n log,\n resolvePath,\n resolveFolderId,\n checkFileExists,\n validateTextFileExtension,\n };\n}\n\n// -----------------------------------------------------------------------------\n// SERVER FACTORY\n// -----------------------------------------------------------------------------\n\nfunction createMcpServer(): Server {\n const s = new Server(\n {\n name: \"google-drive-mcp\",\n version: VERSION,\n },\n {\n capabilities: {\n resources: {},\n tools: {},\n },\n },\n );\n\n s.setRequestHandler(ListResourcesRequestSchema, async (request) => {\n await ensureAuthenticated();\n log('Handling ListResources request', { params: request.params });\n const pageSize = 10;\n const params: {\n pageSize: number,\n fields: string,\n pageToken?: string,\n q: string,\n includeItemsFromAllDrives: boolean,\n supportsAllDrives: boolean\n } = {\n pageSize,\n fields: \"nextPageToken, files(id, name, mimeType)\",\n q: `trashed = false`,\n includeItemsFromAllDrives: true,\n supportsAllDrives: true\n };\n\n if (request.params?.cursor) {\n params.pageToken = request.params.cursor;\n }\n\n const res = await getDrive().files.list(params);\n log('Listed files', { count: res.data.files?.length });\n const files = res.data.files || [];\n\n return {\n resources: files.map((file: drive_v3.Schema$File) => ({\n uri: `gdrive:///${file.id}`,\n mimeType: file.mimeType || 'application/octet-stream',\n name: file.name || 'Untitled',\n })),\n nextCursor: res.data.nextPageToken,\n };\n });\n\n s.setRequestHandler(ReadResourceRequestSchema, async (request) => {\n await ensureAuthenticated();\n log('Handling ReadResource request', { uri: request.params.uri });\n const fileId = request.params.uri.replace(\"gdrive:///\", \"\");\n\n const file = await getDrive().files.get({\n fileId,\n fields: \"mimeType\",\n supportsAllDrives: true\n });\n const mimeType = file.data.mimeType;\n\n if (!mimeType) {\n throw new Error(\"File has no MIME type.\");\n }\n\n if (mimeType.startsWith(\"application/vnd.google-apps\")) {\n let exportMimeType;\n switch (mimeType) {\n case \"application/vnd.google-apps.document\": exportMimeType = \"text/markdown\"; break;\n case \"application/vnd.google-apps.spreadsheet\": exportMimeType = \"text/csv\"; break;\n case \"application/vnd.google-apps.presentation\": exportMimeType = \"text/plain\"; break;\n case \"application/vnd.google-apps.drawing\": exportMimeType = \"image/png\"; break;\n default: exportMimeType = \"text/plain\"; break;\n }\n\n const res = await getDrive().files.export(\n { fileId, mimeType: exportMimeType },\n { responseType: \"text\" },\n );\n\n log('Successfully read resource', { fileId, mimeType });\n return {\n contents: [\n {\n uri: request.params.uri,\n mimeType: exportMimeType,\n text: res.data,\n },\n ],\n };\n } else {\n const res = await getDrive().files.get(\n { fileId, alt: \"media\", supportsAllDrives: true },\n { responseType: \"arraybuffer\" },\n );\n const contentMime = mimeType || \"application/octet-stream\";\n\n if (contentMime.startsWith(\"text/\") || contentMime === \"application/json\") {\n return {\n contents: [\n {\n uri: request.params.uri,\n mimeType: contentMime,\n text: Buffer.from(res.data as ArrayBuffer).toString(\"utf-8\"),\n },\n ],\n };\n } else {\n return {\n contents: [\n {\n uri: request.params.uri,\n mimeType: contentMime,\n blob: Buffer.from(res.data as ArrayBuffer).toString(\"base64\"),\n },\n ],\n };\n }\n }\n });\n\n s.setRequestHandler(ListToolsRequestSchema, async () => {\n return {\n tools: domainModules.flatMap(m => m.toolDefinitions),\n };\n });\n\n s.setRequestHandler(CallToolRequestSchema, async (request) => {\n await ensureAuthenticated();\n log('Handling tool request', { tool: request.params.name });\n\n const ctx = buildToolContext();\n\n try {\n for (const mod of domainModules) {\n const result = await mod.handleTool(request.params.name, request.params.arguments ?? {}, ctx);\n if (result !== null) return result;\n }\n return errorResponse(\"Tool not found\");\n } catch (error) {\n log('Error in tool request handler', { error: (error as Error).message });\n return errorResponse((error as Error).message);\n }\n });\n\n return s;\n}\n\n// Module-level server instance (used by stdio mode and tests)\nconst server = createMcpServer();\n\n// -----------------------------------------------------------------------------\n// CLI FUNCTIONS\n// -----------------------------------------------------------------------------\n\nfunction showHelp(): void {\n console.log(`\nGoogle Drive MCP Server v${VERSION}\n\nUsage:\n npx @yourusername/google-drive-mcp [command] [options]\n\nCommands:\n auth Run the authentication flow\n start Start the MCP server (default)\n version Show version information\n help Show this help message\n\nTransport Options:\n --transport <stdio|http> Transport mode (default: stdio)\n --port <number> HTTP listen port (default: 3100)\n --host <address> HTTP bind address (default: 127.0.0.1)\n\nExamples:\n npx @yourusername/google-drive-mcp auth\n npx @yourusername/google-drive-mcp start\n npx @yourusername/google-drive-mcp start --transport http --port 3100\n npx @yourusername/google-drive-mcp version\n npx @yourusername/google-drive-mcp\n\nEnvironment Variables:\n GOOGLE_DRIVE_OAUTH_CREDENTIALS Path to OAuth credentials file\n GOOGLE_DRIVE_MCP_TOKEN_PATH Path to store authentication tokens\n GOOGLE_DRIVE_MCP_AUTH_PORT Starting port for OAuth callback server (default: 3000, uses 5 consecutive ports)\n\n Transport Configuration:\n MCP_TRANSPORT Transport mode: stdio or http (default: stdio)\n MCP_HTTP_PORT HTTP listen port (default: 3100)\n MCP_HTTP_HOST HTTP bind address (default: 127.0.0.1)\n\n Service Account Mode:\n GOOGLE_APPLICATION_CREDENTIALS Path to service account JSON key file\n\n External OAuth Token Mode:\n GOOGLE_DRIVE_MCP_ACCESS_TOKEN Pre-obtained Google OAuth access token\n GOOGLE_DRIVE_MCP_REFRESH_TOKEN Refresh token for auto-refresh (optional)\n GOOGLE_DRIVE_MCP_CLIENT_ID OAuth client ID (required with refresh token)\n GOOGLE_DRIVE_MCP_CLIENT_SECRET OAuth client secret (required with refresh token)\n`);\n}\n\nfunction showVersion(): void {\n console.log(`Google Drive MCP Server v${VERSION}`);\n}\n\nasync function runAuthServer(): Promise<void> {\n try {\n const oauth2Client = await initializeOAuth2Client();\n const authServerInstance = new AuthServer(oauth2Client);\n const success = await authServerInstance.start(true);\n\n if (!success && !authServerInstance.authCompletedSuccessfully) {\n const { start, end } = authServerInstance.portRange;\n console.error(\n `Authentication failed. Could not start server or validate existing tokens. Check port availability (${start}-${end}) and try again.`\n );\n process.exit(1);\n } else if (authServerInstance.authCompletedSuccessfully) {\n console.log(\"Authentication successful.\");\n process.exit(0);\n }\n\n console.log(\n \"Authentication server started. Please complete the authentication in your browser...\"\n );\n\n const intervalId = setInterval(async () => {\n if (authServerInstance.authCompletedSuccessfully) {\n clearInterval(intervalId);\n await authServerInstance.stop();\n console.log(\"Authentication completed successfully!\");\n process.exit(0);\n }\n }, 1000);\n } catch (error) {\n console.error(\"Authentication failed:\", error);\n process.exit(1);\n }\n}\n\n// -----------------------------------------------------------------------------\n// MAIN EXECUTION\n// -----------------------------------------------------------------------------\n\ninterface CliArgs {\n command: string | undefined;\n transport: 'stdio' | 'http';\n httpPort: number;\n httpHost: string;\n}\n\nfunction parseCliArgs(): CliArgs {\n const args = process.argv.slice(2);\n let command: string | undefined;\n let transport: string | undefined;\n let httpPort: string | undefined;\n let httpHost: string | undefined;\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n\n if (arg === '--version' || arg === '-v' || arg === '--help' || arg === '-h') {\n command = arg;\n continue;\n }\n\n if (arg === '--transport' && i + 1 < args.length) {\n transport = args[++i];\n continue;\n }\n if (arg === '--port' && i + 1 < args.length) {\n httpPort = args[++i];\n continue;\n }\n if (arg === '--host' && i + 1 < args.length) {\n httpHost = args[++i];\n continue;\n }\n\n if (!command && !arg.startsWith('--')) {\n command = arg;\n continue;\n }\n }\n\n const resolvedTransport = transport || process.env.MCP_TRANSPORT || 'stdio';\n if (resolvedTransport !== 'stdio' && resolvedTransport !== 'http') {\n console.error(`Invalid transport: ${resolvedTransport}. Must be \"stdio\" or \"http\".`);\n process.exit(1);\n }\n\n const resolvedPort = parseInt(httpPort || process.env.MCP_HTTP_PORT || '3100', 10);\n if (isNaN(resolvedPort) || resolvedPort < 1 || resolvedPort > 65535) {\n console.error(`Invalid port: ${httpPort || process.env.MCP_HTTP_PORT}. Must be 1-65535.`);\n process.exit(1);\n }\n\n return {\n command,\n transport: resolvedTransport,\n httpPort: resolvedPort,\n httpHost: httpHost || process.env.MCP_HTTP_HOST || '127.0.0.1',\n };\n}\n\nasync function main() {\n const args = parseCliArgs();\n\n switch (args.command) {\n case \"auth\":\n await runAuthServer();\n break;\n case \"start\":\n case undefined:\n if (args.transport === 'http') {\n await startHttpTransport(args);\n } else {\n await startStdioTransport();\n }\n break;\n case \"version\":\n case \"--version\":\n case \"-v\":\n showVersion();\n break;\n case \"help\":\n case \"--help\":\n case \"-h\":\n showHelp();\n break;\n default:\n console.error(`Unknown command: ${args.command}`);\n showHelp();\n process.exit(1);\n }\n}\n\nasync function startStdioTransport(): Promise<void> {\n try {\n console.error(\"Starting Google Drive MCP server (stdio)...\");\n const transport = new StdioServerTransport();\n await server.connect(transport);\n log('Server started successfully');\n\n process.on(\"SIGINT\", async () => {\n await server.close();\n process.exit(0);\n });\n process.on(\"SIGTERM\", async () => {\n await server.close();\n process.exit(0);\n });\n } catch (error) {\n console.error('Failed to start server:', error);\n process.exit(1);\n }\n}\n\ninterface HttpSession {\n transport: StreamableHTTPServerTransport;\n server: Server;\n}\n\n/**\n * Create an Express app with MCP Streamable HTTP routes.\n * Shared by production (startHttpTransport) and tests.\n */\nconst SESSION_IDLE_TIMEOUT_MS = 30 * 60 * 1000; // 30 minutes\n\ninterface CreateHttpAppOptions {\n sessionIdleTimeoutMs?: number;\n}\n\nfunction createHttpApp(host: string, options?: CreateHttpAppOptions) {\n const idleTimeoutMs = options?.sessionIdleTimeoutMs ?? SESSION_IDLE_TIMEOUT_MS;\n const app = createMcpExpressApp({ host });\n const sessions = new Map<string, HttpSession>();\n const sessionTimers = new Map<string, ReturnType<typeof setTimeout>>();\n\n function resetSessionTimer(sid: string) {\n const existing = sessionTimers.get(sid);\n if (existing) clearTimeout(existing);\n sessionTimers.set(sid, setTimeout(async () => {\n const session = sessions.get(sid);\n if (session) {\n log(`Session idle timeout: ${sid}`);\n await session.transport.close();\n await session.server.close();\n sessions.delete(sid);\n }\n sessionTimers.delete(sid);\n }, idleTimeoutMs));\n }\n\n function clearSessionTimer(sid: string) {\n const timer = sessionTimers.get(sid);\n if (timer) {\n clearTimeout(timer);\n sessionTimers.delete(sid);\n }\n }\n\n app.post('/mcp', async (req, res) => {\n try {\n const sessionId = req.headers['mcp-session-id'] as string | undefined;\n\n // If we have an existing session, delegate to it\n if (sessionId && sessions.has(sessionId)) {\n const session = sessions.get(sessionId)!;\n resetSessionTimer(sessionId);\n await session.transport.handleRequest(req, res, req.body);\n return;\n }\n\n // New session: only accept initialize requests\n if (!isInitializeRequest(req.body)) {\n res.status(400).json({\n jsonrpc: '2.0',\n error: { code: -32600, message: 'Bad Request: expected initialize request or valid session ID' },\n id: null,\n });\n return;\n }\n\n // Create a new session\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: () => randomUUID(),\n });\n const sessionServer = createMcpServer();\n\n await sessionServer.connect(transport);\n\n // Track the session once we know its ID (set after handleRequest processes init)\n transport.onclose = () => {\n const sid = transport.sessionId;\n if (sid) {\n clearSessionTimer(sid);\n sessions.delete(sid);\n log(`Session closed: ${sid}`);\n }\n };\n\n await transport.handleRequest(req, res, req.body);\n\n const sid = transport.sessionId;\n if (sid) {\n sessions.set(sid, { transport, server: sessionServer });\n resetSessionTimer(sid);\n log(`New session created: ${sid}`);\n }\n } catch (error) {\n log('Error handling POST /mcp', { error: (error as Error).message });\n if (!res.headersSent) {\n res.status(500).json({\n jsonrpc: '2.0',\n error: { code: -32603, message: 'Internal server error' },\n id: null,\n });\n }\n }\n });\n\n app.get('/mcp', async (req, res) => {\n try {\n const sessionId = req.headers['mcp-session-id'] as string | undefined;\n if (!sessionId || !sessions.has(sessionId)) {\n res.status(400).json({\n jsonrpc: '2.0',\n error: { code: -32600, message: 'Bad Request: missing or invalid session ID' },\n id: null,\n });\n return;\n }\n const session = sessions.get(sessionId)!;\n resetSessionTimer(sessionId);\n await session.transport.handleRequest(req, res);\n } catch (error) {\n log('Error handling GET /mcp', { error: (error as Error).message });\n if (!res.headersSent) {\n res.status(500).json({\n jsonrpc: '2.0',\n error: { code: -32603, message: 'Internal server error' },\n id: null,\n });\n }\n }\n });\n\n app.delete('/mcp', async (req, res) => {\n try {\n const sessionId = req.headers['mcp-session-id'] as string | undefined;\n if (!sessionId || !sessions.has(sessionId)) {\n res.status(400).json({\n jsonrpc: '2.0',\n error: { code: -32600, message: 'Bad Request: missing or invalid session ID' },\n id: null,\n });\n return;\n }\n const session = sessions.get(sessionId)!;\n await session.transport.close();\n await session.server.close();\n sessions.delete(sessionId);\n res.status(200).end();\n } catch (error) {\n log('Error handling DELETE /mcp', { error: (error as Error).message });\n if (!res.headersSent) {\n res.status(500).json({\n jsonrpc: '2.0',\n error: { code: -32603, message: 'Internal server error' },\n id: null,\n });\n }\n }\n });\n\n return { app, sessions };\n}\n\nasync function startHttpTransport(args: CliArgs): Promise<void> {\n try {\n const { httpPort, httpHost } = args;\n console.error(`Starting Google Drive MCP server (HTTP on ${httpHost}:${httpPort})...`);\n\n const { app, sessions } = createHttpApp(httpHost);\n\n const httpServer = app.listen(httpPort, httpHost, () => {\n log(`HTTP server listening on ${httpHost}:${httpPort}`);\n });\n\n const shutdown = async () => {\n log('Shutting down HTTP server...');\n for (const [sid, session] of sessions) {\n await session.transport.close();\n await session.server.close();\n sessions.delete(sid);\n }\n httpServer.close();\n process.exit(0);\n };\n\n process.on(\"SIGINT\", shutdown);\n process.on(\"SIGTERM\", shutdown);\n } catch (error) {\n console.error('Failed to start HTTP server:', error);\n process.exit(1);\n }\n}\n\n// Export server, factory, and main for testing or potential programmatic use\nexport { main, server, createMcpServer, createHttpApp };\n\n/** Inject a fake auth client for testing \u2014 bypasses authenticate(). */\nexport function _setAuthClientForTesting(client: any) {\n authClient = client;\n _drive = null;\n _calendar = null;\n _lastAuthClient = null;\n}\n\n// Run the CLI (skip when imported by tests)\nif (!process.env.MCP_TESTING) {\n main().catch((error) => {\n console.error(\"Fatal error:\", error);\n process.exit(1);\n });\n}\n", "import { OAuth2Client } from 'google-auth-library';\nimport * as fs from 'fs/promises';\nimport { getKeysFilePaths, generateCredentialsErrorMessage, OAuthCredentials } from './utils.js';\n\nfunction parseCredentialsFile(keys: Record<string, unknown>): OAuthCredentials {\n if (keys.installed) {\n const { client_id, client_secret, redirect_uris } = keys.installed as OAuthCredentials;\n return { client_id, client_secret, redirect_uris };\n } else if (keys.web) {\n const { client_id, client_secret, redirect_uris } = keys.web as OAuthCredentials;\n return { client_id, client_secret, redirect_uris };\n } else if (keys.client_id) {\n return {\n client_id: keys.client_id as string,\n client_secret: keys.client_secret as string | undefined,\n redirect_uris: (keys.redirect_uris as string[] | undefined) || ['http://localhost:3000/oauth2callback']\n };\n } else {\n throw new Error('Invalid credentials file format. Expected either \"installed\", \"web\" object or direct client_id field.');\n }\n}\n\nasync function loadCredentialsFromFile(): Promise<OAuthCredentials> {\n const paths = getKeysFilePaths();\n\n for (const keysPath of paths) {\n try {\n const keysContent = await fs.readFile(keysPath, \"utf-8\");\n const keys = JSON.parse(keysContent);\n return parseCredentialsFile(keys);\n } catch (err: unknown) {\n // Re-throw parse/validation errors so the user gets actionable feedback\n if (err instanceof SyntaxError ||\n (err instanceof Error && err.message.includes('Invalid credentials'))) {\n throw new Error(`Invalid credentials file at ${keysPath}: ${(err as Error).message}`);\n }\n // File not found \u2014 try next path\n }\n }\n\n throw new Error(`Credentials file not found. Searched: ${paths.join(', ')}`);\n}\n\nasync function loadCredentialsWithFallback(): Promise<OAuthCredentials> {\n try {\n return await loadCredentialsFromFile();\n } catch (fileError) {\n // Check for legacy client_secret.json\n const legacyPath = process.env.GOOGLE_CLIENT_SECRET_PATH || 'client_secret.json';\n try {\n const legacyContent = await fs.readFile(legacyPath, 'utf-8');\n const legacyKeys = JSON.parse(legacyContent);\n console.error('Warning: Using legacy client_secret.json. Please migrate to gcp-oauth.keys.json');\n \n if (legacyKeys.installed) {\n return legacyKeys.installed;\n } else if (legacyKeys.web) {\n return legacyKeys.web;\n } else {\n throw new Error('Invalid legacy credentials format');\n }\n } catch (_legacyError) {\n // Generate helpful error message\n const errorMessage = generateCredentialsErrorMessage();\n throw new Error(`${errorMessage}\\n\\nOriginal error: ${fileError instanceof Error ? fileError.message : fileError}`);\n }\n }\n}\n\nexport async function initializeOAuth2Client(): Promise<OAuth2Client> {\n try {\n const credentials = await loadCredentialsWithFallback();\n \n // Use the first redirect URI as the default for the base client\n return new OAuth2Client({\n clientId: credentials.client_id,\n clientSecret: credentials.client_secret || undefined,\n redirectUri: credentials.redirect_uris?.[0] || 'http://localhost:3000/oauth2callback',\n });\n } catch (error) {\n throw new Error(`Error loading OAuth keys: ${error instanceof Error ? error.message : error}`);\n }\n}\n\nexport async function loadCredentials(): Promise<{ client_id: string; client_secret?: string }> {\n try {\n const credentials = await loadCredentialsWithFallback();\n \n if (!credentials.client_id) {\n throw new Error('Client ID missing in credentials.');\n }\n return {\n client_id: credentials.client_id,\n client_secret: credentials.client_secret\n };\n } catch (error) {\n throw new Error(`Error loading credentials: ${error instanceof Error ? error.message : error}`);\n }\n}", "import * as path from 'path';\nimport * as os from 'os';\nimport { fileURLToPath } from 'url';\n\n// Helper to get the project root directory reliably\nfunction getProjectRoot(): string {\n const __dirname = path.dirname(fileURLToPath(import.meta.url));\n // In build output (e.g., dist/auth/utils.js), __dirname is .../dist/auth\n // Go up TWO levels to get the project root\n const projectRoot = path.join(__dirname, \"..\", \"..\");\n return path.resolve(projectRoot);\n}\n\n// Returns the config directory for google-drive-mcp, following XDG Base Directory spec.\nfunction getConfigDir(): string {\n const configHome = process.env.XDG_CONFIG_HOME ||\n path.join(os.homedir(), '.config');\n return path.join(configHome, 'google-drive-mcp');\n}\n\n// Returns the absolute path for the saved token file.\n// Uses XDG Base Directory spec with fallback to home directory\nexport function getSecureTokenPath(): string {\n // Check for custom token path environment variable first\n const customTokenPath = process.env.GOOGLE_DRIVE_MCP_TOKEN_PATH;\n if (customTokenPath) {\n return path.resolve(customTokenPath);\n }\n\n return path.join(getConfigDir(), 'tokens.json');\n}\n\n// Returns the legacy token path for backward compatibility\nexport function getLegacyTokenPath(): string {\n const projectRoot = getProjectRoot();\n return path.join(projectRoot, \".gcp-saved-tokens.json\");\n}\n\n// Additional legacy paths to check\nexport function getAdditionalLegacyPaths(): string[] {\n return [\n process.env.GOOGLE_TOKEN_PATH,\n path.join(process.cwd(), 'google-tokens.json'),\n path.join(process.cwd(), '.gcp-saved-tokens.json')\n ].filter(Boolean) as string[];\n}\n\n// Returns all candidate paths for the credentials file, in priority order:\n// 1. Environment variable GOOGLE_DRIVE_OAUTH_CREDENTIALS (highest priority)\n// 2. Config directory ~/.config/google-drive-mcp/gcp-oauth.keys.json\n// 3. Project root directory (legacy fallback)\nexport function getKeysFilePaths(): string[] {\n const paths: string[] = [];\n\n const envCredentialsPath = process.env.GOOGLE_DRIVE_OAUTH_CREDENTIALS;\n if (envCredentialsPath) {\n paths.push(path.resolve(envCredentialsPath));\n }\n\n paths.push(path.join(getConfigDir(), 'gcp-oauth.keys.json'));\n\n const projectRoot = getProjectRoot();\n paths.push(path.join(projectRoot, \"gcp-oauth.keys.json\"));\n\n return paths;\n}\n\n// Interface for OAuth credentials\nexport interface OAuthCredentials {\n client_id: string;\n client_secret?: string;\n redirect_uris?: string[];\n}\n\n// Generate helpful error message for missing credentials\nexport function generateCredentialsErrorMessage(): string {\n const configDir = getConfigDir();\n\n return `\nOAuth credentials not found. Please provide credentials using one of these methods:\n\n1. Config directory (recommended):\n Place your gcp-oauth.keys.json file in: ${configDir}/\n\n2. Environment variable:\n Set GOOGLE_DRIVE_OAUTH_CREDENTIALS to the path of your credentials file:\n export GOOGLE_DRIVE_OAUTH_CREDENTIALS=\"/path/to/gcp-oauth.keys.json\"\n\nToken storage:\n- Tokens are saved to: ${getSecureTokenPath()}\n- To use a custom token location, set GOOGLE_DRIVE_MCP_TOKEN_PATH environment variable\n\nTo get OAuth credentials:\n1. Go to the Google Cloud Console (https://console.cloud.google.com/)\n2. Create or select a project\n3. Enable the Google Drive, Docs, Sheets, and Slides APIs\n4. Create OAuth 2.0 credentials (Desktop app type)\n5. Download the credentials file as gcp-oauth.keys.json\n`.trim();\n}", "import express from 'express';\nimport { OAuth2Client } from 'google-auth-library';\nimport { TokenManager } from './tokenManager.js';\nimport http from 'http';\nimport open from 'open';\nimport { loadCredentials } from './client.js';\nimport { resolveOAuthScopes } from './scopes.js';\n\nconst SCOPES = resolveOAuthScopes();\n\nexport class AuthServer {\n private baseOAuth2Client: OAuth2Client; // Used by TokenManager for validation/refresh\n private flowOAuth2Client: OAuth2Client | null = null; // Used specifically for the auth code flow\n private app: express.Express;\n private server: http.Server | null = null;\n private tokenManager: TokenManager;\n public readonly portRange: { start: number; end: number };\n public authCompletedSuccessfully = false; // Flag for standalone script\n\n constructor(oauth2Client: OAuth2Client) {\n this.baseOAuth2Client = oauth2Client;\n this.tokenManager = new TokenManager(oauth2Client);\n this.app = express();\n const raw = process.env.GOOGLE_DRIVE_MCP_AUTH_PORT;\n const portStart = raw ? Number(raw) : 3000;\n if (!Number.isInteger(portStart) || portStart < 1 || portStart > 65531) {\n throw new Error(\n `Invalid GOOGLE_DRIVE_MCP_AUTH_PORT: \"${raw}\". Must be an integer between 1 and 65531.`\n );\n }\n this.portRange = { start: portStart, end: portStart + 4 };\n this.setupRoutes();\n }\n\n private setupRoutes(): void {\n this.app.get('/', (req, res) => {\n // Generate the URL using the active flow client if available, else base\n const clientForUrl = this.flowOAuth2Client || this.baseOAuth2Client;\n const authUrl = clientForUrl.generateAuthUrl({\n access_type: 'offline',\n scope: SCOPES,\n prompt: 'consent'\n });\n res.send(`<h1>Google Drive Authentication</h1><a href=\"${authUrl}\">Authenticate with Google</a>`);\n });\n\n this.app.get('/oauth2callback', async (req, res) => {\n const code = req.query.code as string;\n if (!code) {\n res.status(400).send('Authorization code missing');\n return;\n }\n // IMPORTANT: Use the flowOAuth2Client to exchange the code\n if (!this.flowOAuth2Client) {\n res.status(500).send('Authentication flow not properly initiated.');\n return;\n }\n try {\n const { tokens } = await this.flowOAuth2Client.getToken(code);\n // Save tokens using the TokenManager (which uses the base client)\n await this.tokenManager.saveTokens(tokens);\n this.authCompletedSuccessfully = true;\n\n // Get the path where tokens were saved\n const tokenPath = this.tokenManager.getTokenPath();\n\n // Send a more informative HTML response including the path\n res.send(`\n <!DOCTYPE html>\n <html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Authentication Successful</title>\n <style>\n body { font-family: sans-serif; display: flex; justify-content: center; align-items: center; height: 100vh; background-color: #f4f4f4; margin: 0; }\n .container { text-align: center; padding: 2em; background-color: #fff; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }\n h1 { color: #4CAF50; }\n p { color: #333; margin-bottom: 0.5em; }\n code { background-color: #eee; padding: 0.2em 0.4em; border-radius: 3px; font-size: 0.9em; }\n </style>\n </head>\n <body>\n <div class=\"container\">\n <h1>Authentication Successful!</h1>\n <p>Your authentication tokens have been saved successfully to:</p>\n <p><code>${tokenPath}</code></p>\n <p>You can now close this browser window.</p>\n </div>\n </body>\n </html>\n `);\n } catch (error: unknown) {\n this.authCompletedSuccessfully = false;\n const message = error instanceof Error ? error.message : 'Unknown error';\n // Send an HTML error response\n res.status(500).send(`\n <!DOCTYPE html>\n <html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Authentication Failed</title>\n <style>\n body { font-family: sans-serif; display: flex; justify-content: center; align-items: center; height: 100vh; background-color: #f4f4f4; margin: 0; }\n .container { text-align: center; padding: 2em; background-color: #fff; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }\n h1 { color: #F44336; }\n p { color: #333; }\n </style>\n </head>\n <body>\n <div class=\"container\">\n <h1>Authentication Failed</h1>\n <p>An error occurred during authentication:</p>\n <p><code>${message}</code></p>\n <p>Please try again or check the server logs.</p>\n </div>\n </body>\n </html>\n `);\n }\n });\n }\n\n async start(openBrowser = true): Promise<boolean> {\n if (await this.tokenManager.validateTokens()) {\n this.authCompletedSuccessfully = true;\n return true;\n }\n \n // Try to start the server and get the port\n const port = await this.startServerOnAvailablePort();\n if (port === null) {\n this.authCompletedSuccessfully = false;\n return false;\n }\n\n // Successfully started server on `port`. Now create the flow-specific OAuth client.\n try {\n const { client_id, client_secret } = await loadCredentials();\n this.flowOAuth2Client = new OAuth2Client(\n client_id,\n client_secret || undefined,\n `http://localhost:${port}/oauth2callback`\n );\n } catch (error) {\n // Could not load credentials, cannot proceed with auth flow\n console.error('Failed to load credentials for auth flow:', error);\n this.authCompletedSuccessfully = false;\n await this.stop(); // Stop the server we just started\n return false;\n }\n\n if (openBrowser) {\n // Generate Auth URL using the newly created flow client\n const authorizeUrl = this.flowOAuth2Client.generateAuthUrl({\n access_type: 'offline',\n scope: SCOPES,\n prompt: 'consent'\n });\n \n console.error('\\n\uD83D\uDD10 AUTHENTICATION REQUIRED');\n console.error('\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550');\n console.error('\\nOpening your browser to authenticate...');\n console.error(`If the browser doesn't open, visit:\\n${authorizeUrl}\\n`);\n \n await open(authorizeUrl);\n }\n\n return true; // Auth flow initiated\n }\n\n private async startServerOnAvailablePort(): Promise<number | null> {\n for (let port = this.portRange.start; port <= this.portRange.end; port++) {\n try {\n await new Promise<void>((resolve, reject) => {\n // Create a temporary server instance to test the port\n const testServer = this.app.listen(port, () => {\n this.server = testServer; // Assign to class property *only* if successful\n console.error(`Authentication server listening on http://localhost:${port}`);\n resolve();\n });\n testServer.on('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'EADDRINUSE') {\n // Port is in use, close the test server and reject\n testServer.close(() => reject(err)); \n } else {\n // Other error, reject\n reject(err);\n }\n });\n });\n return port; // Port successfully bound\n } catch (error: unknown) {\n // Check if it's EADDRINUSE, otherwise rethrow or handle\n if (!(error instanceof Error && 'code' in error && (error as any).code === 'EADDRINUSE')) {\n // An unexpected error occurred during server start\n console.error('Failed to start auth server:', error);\n return null;\n }\n // EADDRINUSE occurred, loop continues\n }\n }\n console.error('No available ports for authentication server (tried ports', this.portRange.start, '-', this.portRange.end, ')');\n return null; // No port found\n }\n\n public getRunningPort(): number | null {\n if (this.server) {\n const address = this.server.address();\n if (typeof address === 'object' && address !== null) {\n return address.port;\n }\n }\n return null;\n }\n\n async stop(): Promise<void> {\n return new Promise((resolve, reject) => {\n if (this.server) {\n this.server.close((err) => {\n if (err) {\n reject(err);\n } else {\n this.server = null;\n resolve();\n }\n });\n } else {\n resolve();\n }\n });\n }\n}", "import { OAuth2Client, Credentials } from 'google-auth-library';\nimport * as fs from 'fs/promises';\nimport * as path from 'path';\nimport { getSecureTokenPath, getLegacyTokenPath, getAdditionalLegacyPaths } from './utils.js';\nimport { GaxiosError } from 'gaxios';\n\nexport class TokenManager {\n private oauth2Client: OAuth2Client;\n private tokenPath: string;\n\n constructor(oauth2Client: OAuth2Client) {\n this.oauth2Client = oauth2Client;\n this.tokenPath = getSecureTokenPath();\n this.setupTokenRefresh();\n }\n\n // Method to expose the token path\n public getTokenPath(): string {\n return this.tokenPath;\n }\n\n private async ensureTokenDirectoryExists(): Promise<void> {\n try {\n const dir = path.dirname(this.tokenPath);\n await fs.mkdir(dir, { recursive: true });\n } catch (error: unknown) {\n // Ignore errors if directory already exists, re-throw others\n if (error instanceof Error && 'code' in error && (error as any).code !== 'EEXIST') {\n console.error('Failed to create token directory:', error);\n throw error;\n }\n }\n }\n\n private setupTokenRefresh(): void {\n this.oauth2Client.on(\"tokens\", async (newTokens) => {\n try {\n await this.ensureTokenDirectoryExists();\n const currentTokens = JSON.parse(await fs.readFile(this.tokenPath, \"utf-8\"));\n const updatedTokens = {\n ...currentTokens,\n ...newTokens,\n refresh_token: newTokens.refresh_token || currentTokens.refresh_token,\n };\n await fs.writeFile(this.tokenPath, JSON.stringify(updatedTokens, null, 2), {\n mode: 0o600,\n });\n console.error(\"Tokens updated and saved\");\n } catch (error: unknown) {\n // Handle case where currentTokens might not exist yet\n if (error instanceof Error && 'code' in error && (error as any).code === 'ENOENT') { \n try {\n await fs.writeFile(this.tokenPath, JSON.stringify(newTokens, null, 2), { mode: 0o600 });\n console.error(\"New tokens saved\");\n } catch (writeError) {\n console.error(\"Error saving initial tokens:\", writeError);\n }\n } else {\n console.error(\"Error saving updated tokens:\", error);\n }\n }\n });\n }\n\n private async migrateLegacyTokens(): Promise<boolean> {\n // Check all possible legacy locations\n const legacyPaths = [getLegacyTokenPath(), ...getAdditionalLegacyPaths()];\n \n for (const legacyPath of legacyPaths) {\n try {\n // Check if legacy tokens exist\n if (!(await fs.access(legacyPath).then(() => true).catch(() => false))) {\n continue; // Try next location\n }\n\n // Read legacy tokens\n const legacyTokens = JSON.parse(await fs.readFile(legacyPath, \"utf-8\"));\n \n if (!legacyTokens || typeof legacyTokens !== \"object\") {\n console.error(\"Invalid legacy token format at\", legacyPath, \", skipping\");\n continue;\n }\n\n // Ensure new token directory exists\n await this.ensureTokenDirectoryExists();\n \n // Copy to new location\n await fs.writeFile(this.tokenPath, JSON.stringify(legacyTokens, null, 2), {\n mode: 0o600,\n });\n \n console.error(\"Migrated tokens from legacy location:\", legacyPath, \"to:\", this.tokenPath);\n \n // Optionally remove legacy file after successful migration\n try {\n await fs.unlink(legacyPath);\n console.error(\"Removed legacy token file\");\n } catch (unlinkErr) {\n console.error(\"Warning: Could not remove legacy token file:\", unlinkErr);\n }\n \n return true;\n } catch (error) {\n console.error(\"Error migrating legacy tokens from\", legacyPath, \":\", error);\n // Continue to next location\n }\n }\n \n return false; // No legacy tokens found or migrated\n }\n\n async loadSavedTokens(): Promise<boolean> {\n try {\n await this.ensureTokenDirectoryExists();\n \n // Check if current token file exists\n const tokenExists = await fs.access(this.tokenPath).then(() => true).catch(() => false);\n \n // If no current tokens, try to migrate from legacy location\n if (!tokenExists) {\n const migrated = await this.migrateLegacyTokens();\n if (!migrated) {\n console.error(\"No token file found at:\", this.tokenPath);\n return false;\n }\n }\n\n const tokens = JSON.parse(await fs.readFile(this.tokenPath, \"utf-8\"));\n\n if (!tokens || typeof tokens !== \"object\") {\n console.error(\"Invalid token format in file:\", this.tokenPath);\n return false;\n }\n\n this.oauth2Client.setCredentials(tokens);\n console.error('Tokens loaded and set on OAuth2Client:', {\n hasAccessToken: !!tokens.access_token,\n hasRefreshToken: !!tokens.refresh_token,\n tokenLength: tokens.access_token?.length,\n expiryDate: tokens.expiry_date,\n scope: tokens.scope\n });\n console.error('OAuth2Client after setCredentials:', {\n hasCredentials: !!this.oauth2Client.credentials,\n credentialsAccessToken: !!this.oauth2Client.credentials?.access_token\n });\n return true;\n } catch (error: unknown) {\n console.error(\"Error loading tokens:\", error);\n // Attempt to delete potentially corrupted token file\n if (error instanceof Error && 'code' in error && (error as any).code !== 'ENOENT') { \n try { \n await fs.unlink(this.tokenPath); \n console.error(\"Removed potentially corrupted token file\") \n } catch (_unlinkErr) { /* ignore */ }\n }\n return false;\n }\n }\n\n async refreshTokensIfNeeded(): Promise<boolean> {\n const expiryDate = this.oauth2Client.credentials.expiry_date;\n const isExpired = expiryDate\n ? Date.now() >= expiryDate - 5 * 60 * 1000 // 5 minute buffer\n : !this.oauth2Client.credentials.access_token; // No token means we need one\n\n if (isExpired && this.oauth2Client.credentials.refresh_token) {\n console.error(\"Auth token expired or nearing expiry, refreshing...\");\n try {\n const response = await this.oauth2Client.refreshAccessToken();\n const newTokens = response.credentials;\n\n if (!newTokens.access_token) {\n throw new Error(\"Received invalid tokens during refresh\");\n }\n // The 'tokens' event listener should handle saving\n this.oauth2Client.setCredentials(newTokens);\n console.error(\"Token refreshed successfully\");\n return true;\n } catch (refreshError) {\n if (refreshError instanceof GaxiosError && refreshError.response?.data?.error === 'invalid_grant') {\n console.error(\"Error refreshing auth token: Invalid grant. Token likely expired or revoked. Please re-authenticate.\");\n // Optionally clear the potentially invalid tokens here\n await this.clearTokens(); \n return false; // Indicate failure due to invalid grant\n } else {\n // Handle other refresh errors\n console.error(\"Error refreshing auth token:\", refreshError);\n return false;\n }\n }\n } else if (!this.oauth2Client.credentials.access_token && !this.oauth2Client.credentials.refresh_token) {\n console.error(\"No access or refresh token available. Please re-authenticate.\");\n return false;\n } else {\n // Token is valid or no refresh token available\n return true;\n }\n }\n\n async validateTokens(): Promise<boolean> {\n if (!this.oauth2Client.credentials || !this.oauth2Client.credentials.access_token) {\n // Try loading first if no credentials set\n if (!(await this.loadSavedTokens())) {\n return false; // No saved tokens to load\n }\n // Check again after loading\n if (!this.oauth2Client.credentials || !this.oauth2Client.credentials.access_token) {\n return false; // Still no token after loading\n }\n }\n return this.refreshTokensIfNeeded();\n }\n\n async saveTokens(tokens: Credentials): Promise<void> {\n try {\n await this.ensureTokenDirectoryExists();\n await fs.writeFile(this.tokenPath, JSON.stringify(tokens, null, 2), { mode: 0o600 });\n this.oauth2Client.setCredentials(tokens);\n console.error(\"Tokens saved successfully to:\", this.tokenPath);\n } catch (error: unknown) {\n console.error(\"Error saving tokens:\", error);\n throw error;\n }\n }\n\n async clearTokens(): Promise<void> {\n try {\n this.oauth2Client.setCredentials({}); // Clear in memory\n await fs.unlink(this.tokenPath);\n console.error(\"Tokens cleared successfully\");\n } catch (error: unknown) {\n if (error instanceof Error && 'code' in error && (error as any).code === 'ENOENT') {\n // File already gone, which is fine\n console.error(\"Token file already deleted\");\n } else {\n console.error(\"Error clearing tokens:\", error);\n // Don't re-throw, clearing is best-effort\n }\n }\n }\n}", "// ---------------------------------------------------------------------------\n// Shared OAuth scope constants & resolution\n// ---------------------------------------------------------------------------\n\nexport const SCOPE_ALIASES: Record<string, string> = {\n drive: 'https://www.googleapis.com/auth/drive',\n 'drive.file': 'https://www.googleapis.com/auth/drive.file',\n 'drive.readonly': 'https://www.googleapis.com/auth/drive.readonly',\n documents: 'https://www.googleapis.com/auth/documents',\n spreadsheets: 'https://www.googleapis.com/auth/spreadsheets',\n presentations: 'https://www.googleapis.com/auth/presentations',\n calendar: 'https://www.googleapis.com/auth/calendar',\n 'calendar.events': 'https://www.googleapis.com/auth/calendar.events',\n};\n\nexport const SCOPE_PRESETS: Record<string, string[]> = {\n readonly: ['drive.readonly'],\n 'content-editor': ['drive.file', 'documents', 'spreadsheets', 'presentations'],\n full: ['drive', 'documents', 'spreadsheets', 'presentations', 'calendar', 'calendar.events'],\n};\n\nexport const DEFAULT_SCOPES: readonly string[] = [\n 'drive', 'drive.file', 'drive.readonly',\n 'documents', 'spreadsheets', 'presentations',\n 'calendar', 'calendar.events',\n].map((s) => SCOPE_ALIASES[s]);\n\n/**\n * Resolve OAuth scopes from `GOOGLE_DRIVE_MCP_SCOPES` env var.\n * Accepts comma-separated aliases (e.g. \"drive,documents\") or full URLs.\n * Throws on unknown aliases so mis-configurations surface immediately.\n */\nexport function resolveOAuthScopes(): string[] {\n const raw = process.env.GOOGLE_DRIVE_MCP_SCOPES?.trim();\n if (!raw) return [...DEFAULT_SCOPES];\n\n const scopes = raw\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean)\n .map((s) => {\n if (SCOPE_ALIASES[s]) return SCOPE_ALIASES[s];\n if (s.startsWith('https://')) return s;\n const known = Object.keys(SCOPE_ALIASES).join(', ');\n throw new Error(\n `Unknown OAuth scope alias \"${s}\". Use a full URL (https://...) or one of: ${known}`\n );\n });\n\n if (scopes.length === 0) return [...DEFAULT_SCOPES];\n return [...new Set(scopes)];\n}\n", "// ---------------------------------------------------------------------------\n// External authentication modes: Service Account & pre-obtained OAuth tokens\n// ---------------------------------------------------------------------------\n\nimport { OAuth2Client } from 'google-auth-library';\nimport { GoogleAuth } from 'google-auth-library';\nimport { DEFAULT_SCOPES } from './scopes.js';\n\n// ---------------------------------------------------------------------------\n// Service Account mode\n// ---------------------------------------------------------------------------\n\n/** True when `GOOGLE_APPLICATION_CREDENTIALS` is set (standard Google convention). */\nexport function isServiceAccountMode(): boolean {\n return !!process.env.GOOGLE_APPLICATION_CREDENTIALS;\n}\n\n/**\n * Create an authorized client from a service account JSON key file.\n * `GoogleAuth` handles JWT signing and token refresh automatically.\n */\nexport async function createServiceAccountAuth(): Promise<any> {\n const keyFile = process.env.GOOGLE_APPLICATION_CREDENTIALS!;\n console.error(`Using service account credentials from ${keyFile}`);\n\n const auth = new GoogleAuth({\n keyFile,\n scopes: [...DEFAULT_SCOPES],\n });\n\n const client = await auth.getClient();\n console.error('Service account authentication successful');\n return client;\n}\n\n// ---------------------------------------------------------------------------\n// External OAuth Token mode\n// ---------------------------------------------------------------------------\n\n/** True when `GOOGLE_DRIVE_MCP_ACCESS_TOKEN` is set. */\nexport function isExternalTokenMode(): boolean {\n return !!process.env.GOOGLE_DRIVE_MCP_ACCESS_TOKEN;\n}\n\n/**\n * Validate that the env-var combination makes sense.\n * Throws with an actionable message on mis-configuration.\n */\nexport function validateExternalTokenConfig(): void {\n const accessToken = process.env.GOOGLE_DRIVE_MCP_ACCESS_TOKEN?.trim();\n if (!accessToken) {\n throw new Error(\n 'GOOGLE_DRIVE_MCP_ACCESS_TOKEN is set but empty. Provide a valid OAuth access token.'\n );\n }\n\n const refreshToken = process.env.GOOGLE_DRIVE_MCP_REFRESH_TOKEN?.trim();\n const clientId = process.env.GOOGLE_DRIVE_MCP_CLIENT_ID?.trim();\n const clientSecret = process.env.GOOGLE_DRIVE_MCP_CLIENT_SECRET?.trim();\n\n if (refreshToken) {\n if (!clientId || !clientSecret) {\n throw new Error(\n 'GOOGLE_DRIVE_MCP_REFRESH_TOKEN is set but GOOGLE_DRIVE_MCP_CLIENT_ID and/or ' +\n 'GOOGLE_DRIVE_MCP_CLIENT_SECRET are missing. All three are required for automatic token refresh.'\n );\n }\n }\n\n // Warn about partial client credential sets (one without the other)\n if ((clientId && !clientSecret) || (!clientId && clientSecret)) {\n throw new Error(\n 'Both GOOGLE_DRIVE_MCP_CLIENT_ID and GOOGLE_DRIVE_MCP_CLIENT_SECRET must be provided together.'\n );\n }\n}\n\n/**\n * Create an OAuth2Client pre-loaded with externally-obtained credentials.\n * When a refresh token + client credentials are provided, the client will\n * auto-refresh transparently.\n */\nexport function createExternalOAuth2Client(): OAuth2Client {\n const accessToken = process.env.GOOGLE_DRIVE_MCP_ACCESS_TOKEN!.trim();\n const refreshToken = process.env.GOOGLE_DRIVE_MCP_REFRESH_TOKEN?.trim();\n const clientId = process.env.GOOGLE_DRIVE_MCP_CLIENT_ID?.trim();\n const clientSecret = process.env.GOOGLE_DRIVE_MCP_CLIENT_SECRET?.trim();\n\n const oauth2Client = new OAuth2Client(clientId, clientSecret);\n\n oauth2Client.setCredentials({\n access_token: accessToken,\n refresh_token: refreshToken || undefined,\n });\n\n if (!refreshToken) {\n console.error(\n 'Warning: No refresh token provided. The access token will not auto-refresh when it expires.'\n );\n } else {\n console.error('External OAuth tokens configured with auto-refresh support.');\n }\n\n return oauth2Client;\n}\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';\nimport {\n isServiceAccountMode, createServiceAccountAuth,\n isExternalTokenMode, validateExternalTokenConfig,\n createExternalOAuth2Client,\n} from './auth/externalAuth.js';\n\nexport { TokenManager } from './auth/tokenManager.js';\nexport { initializeOAuth2Client } from './auth/client.js';\nexport { AuthServer } from './auth/server.js';\nexport { SCOPE_ALIASES, SCOPE_PRESETS, DEFAULT_SCOPES, resolveOAuthScopes } from './auth/scopes.js';\nexport {\n isServiceAccountMode, createServiceAccountAuth,\n isExternalTokenMode, validateExternalTokenConfig,\n createExternalOAuth2Client,\n} from './auth/externalAuth.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 // Priority 1: Service account\n if (isServiceAccountMode()) {\n return await createServiceAccountAuth();\n }\n\n // Priority 2: External OAuth tokens\n if (isExternalTokenMode()) {\n validateExternalTokenConfig();\n return createExternalOAuth2Client();\n }\n\n // Priority 3: Existing local OAuth flow\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(() => {\n if (authServer.authCompletedSuccessfully) {\n clearInterval(intervalId);\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}", "// -----------------------------------------------------------------------------\n// Pure utility functions extracted from index.ts for testability\n// -----------------------------------------------------------------------------\n\n// ---------------------------------------------------------------------------\n// Calendar helpers\n// ---------------------------------------------------------------------------\n\nexport interface CalendarEventOverrides {\n summary?: string;\n description?: string;\n location?: string;\n start?: any;\n end?: any;\n attendees?: string[];\n [key: string]: any;\n}\n\n/**\n * Build the event resource for an updateCalendarEvent call by merging user\n * overrides onto the existing event while excluding read-only fields.\n *\n * Rules:\n * - User overrides win when explicitly provided (even if empty string / empty array)\n * - Existing values are preserved when the override is `undefined`\n * - Attendees are mapped from `string[]` \u2192 `{email}[]`\n * - Only mutable fields are included; read-only fields (id, kind, etag, htmlLink,\n * iCalUID, creator, organizer, sequence, \u2026) are never forwarded\n */\nexport function buildCalendarEventUpdate(existing: any, overrides: CalendarEventOverrides): any {\n return {\n summary: overrides.summary !== undefined ? overrides.summary : existing.summary,\n description: overrides.description !== undefined ? overrides.description : existing.description,\n location: overrides.location !== undefined ? overrides.location : existing.location,\n start: overrides.start || existing.start,\n end: overrides.end || existing.end,\n attendees: overrides.attendees !== undefined\n ? overrides.attendees.map((email: string) => ({ email }))\n : existing.attendees,\n recurrence: existing.recurrence,\n visibility: existing.visibility,\n reminders: existing.reminders,\n };\n}\n\n/**\n * Get file extension from a filename (lowercase).\n */\nexport function getExtensionFromFilename(filename: string): string {\n return filename.split('.').pop()?.toLowerCase() || '';\n}\n\nexport const TEXT_MIME_TYPES: Record<string, string> = {\n txt: 'text/plain',\n md: 'text/markdown',\n};\n\n/**\n * Get the MIME type for a text file from its filename.\n * Falls back to 'text/plain' for unknown extensions.\n */\nexport function getMimeTypeFromFilename(filename: string): string {\n const ext = getExtensionFromFilename(filename);\n return TEXT_MIME_TYPES[ext] || 'text/plain';\n}\n\n/**\n * Escape a string for use in a Google Drive API query.\n * Escapes backslashes and single quotes.\n */\nexport function escapeDriveQuery(value: string): string {\n return value.replace(/\\\\/g, \"\\\\\\\\\").replace(/'/g, \"\\\\'\");\n}\n\n/**\n * Parse a Sheets A1 range reference (e.g. \"'My Sheet'!A1:B2\") into its\n * sheet name and cell range components.\n *\n * - Strips surrounding single quotes from the sheet name\n * - Defaults to 'Sheet1' when no sheet prefix is present\n */\nexport function parseA1Range(range: string): { sheetName: string; cellRange: string } {\n if (range.includes('!')) {\n const sheetName = range.split('!')[0].replace(/^'+|'+$/g, '');\n const cellRange = range.split('!')[1];\n return { sheetName, cellRange };\n }\n return { sheetName: 'Sheet1', cellRange: range };\n}\n\n/**\n * Convert column letters to a zero-based index (A=0, B=1, ... Z=25, AA=26).\n */\nexport function colToIndex(col: string): number {\n let num = 0;\n for (let i = 0; i < col.length; i++) {\n num = num * 26 + (col.charCodeAt(i) - 'A'.charCodeAt(0) + 1);\n }\n return num - 1;\n}\n\nexport interface GridRange {\n sheetId: number;\n startColumnIndex?: number;\n startRowIndex?: number;\n endColumnIndex?: number;\n endRowIndex?: number;\n}\n\n/**\n * Convert an A1 notation string (e.g. \"A1:C5\") into a Sheets GridRange object.\n * Supports ranges, single cells, full-row (\"1:3\"), and full-column (\"A:C\") notation.\n */\nexport function convertA1ToGridRange(a1Notation: string, sheetId: number): GridRange {\n const rangeRegex = /^([A-Z]*)([0-9]*)(:([A-Z]*)([0-9]*))?$/;\n const match = a1Notation.match(rangeRegex);\n\n if (!match) {\n throw new Error(`Invalid A1 notation: ${a1Notation}`);\n }\n\n const [, startCol, startRow, , endCol, endRow] = match;\n\n const gridRange: GridRange = { sheetId };\n\n if (startCol) gridRange.startColumnIndex = colToIndex(startCol);\n if (startRow) gridRange.startRowIndex = parseInt(startRow) - 1;\n\n if (endCol) {\n gridRange.endColumnIndex = colToIndex(endCol) + 1;\n } else if (startCol && !endCol) {\n gridRange.endColumnIndex = gridRange.startColumnIndex! + 1;\n }\n\n if (endRow) {\n gridRange.endRowIndex = parseInt(endRow);\n } else if (startRow && !endRow) {\n gridRange.endRowIndex = gridRange.startRowIndex! + 1;\n }\n\n return gridRange;\n}\n", "import type { drive_v3, calendar_v3 } from 'googleapis';\nimport type { google as GoogleApisType } from 'googleapis';\n\nexport interface ToolResult {\n [key: string]: unknown;\n content: Array<{ type: string; text: string }>;\n isError?: boolean;\n}\n\nexport interface ToolDefinition {\n name: string;\n description: string;\n inputSchema: Record<string, unknown>;\n}\n\nexport interface ToolContext {\n authClient: any;\n google: typeof GoogleApisType;\n getDrive: () => drive_v3.Drive;\n getCalendar: () => calendar_v3.Calendar;\n log: (message: string, data?: any) => void;\n resolvePath: (pathStr: string) => Promise<string>;\n resolveFolderId: (input: string | undefined) => Promise<string>;\n checkFileExists: (name: string, parentFolderId?: string) => Promise<string | null>;\n validateTextFileExtension: (name: string) => void;\n}\n\nexport function errorResponse(message: string): ToolResult {\n return { content: [{ type: \"text\", text: `Error: ${message}` }], isError: true };\n}\n", "import { z } from 'zod';\nimport type { drive_v3 } from 'googleapis';\nimport { existsSync, statSync, createReadStream } from 'fs';\nimport { mkdtemp, readFile, writeFile, rm } from 'fs/promises';\nimport { tmpdir } from 'os';\nimport { basename, extname, join } from 'path';\nimport { PDFDocument } from 'pdf-lib';\nimport type { ToolDefinition, ToolContext, ToolResult } from '../types.js';\nimport { errorResponse } from '../types.js';\nimport { escapeDriveQuery, getMimeTypeFromFilename, TEXT_MIME_TYPES } from '../utils.js';\nimport { downloadDriveFile, GOOGLE_WORKSPACE_EXPORT_FORMATS } from '../download-file.js';\nimport { getSecureTokenPath } from '../auth/utils.js';\nimport { SCOPE_ALIASES, SCOPE_PRESETS, resolveOAuthScopes } from '../auth/scopes.js';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst FOLDER_MIME_TYPE = 'application/vnd.google-apps.folder';\nconst SHORTCUT_MIME_TYPE = 'application/vnd.google-apps.shortcut';\n\n// MIME types for binary file uploads (extension \u2192 MIME)\nconst BINARY_MIME_TYPES: Record<string, string> = {\n jpg: 'image/jpeg', jpeg: 'image/jpeg', png: 'image/png', gif: 'image/gif',\n webp: 'image/webp', svg: 'image/svg+xml', bmp: 'image/bmp', ico: 'image/x-icon',\n mp3: 'audio/mpeg', wav: 'audio/wav', ogg: 'audio/ogg', m4a: 'audio/mp4',\n aac: 'audio/aac', flac: 'audio/flac', opus: 'audio/opus',\n mp4: 'video/mp4', webm: 'video/webm', avi: 'video/x-msvideo', mov: 'video/quicktime',\n mkv: 'video/x-matroska', '3gp': 'video/3gpp',\n pdf: 'application/pdf', zip: 'application/zip', gz: 'application/gzip',\n tar: 'application/x-tar', json: 'application/json', xml: 'application/xml',\n csv: 'text/csv', html: 'text/html', css: 'text/css', js: 'application/javascript',\n doc: 'application/msword', docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n xls: 'application/vnd.ms-excel', xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n ppt: 'application/vnd.ms-powerpoint', pptx: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',\n};\n\n// ---------------------------------------------------------------------------\n// Zod schemas\n// ---------------------------------------------------------------------------\n\nconst SearchSchema = z.object({\n query: z.string().min(1, \"Search query is required\"),\n pageSize: z.number().int().min(1).max(100).optional(),\n pageToken: z.string().optional(),\n rawQuery: z.boolean().optional(),\n});\n\nconst CreateTextFileSchema = z.object({\n name: z.string().min(1, \"File name is required\"),\n content: z.string(),\n parentFolderId: z.string().optional()\n});\n\nconst UpdateTextFileSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\"),\n content: z.string(),\n name: z.string().optional()\n});\n\nconst CreateFolderSchema = z.object({\n name: z.string().min(1, \"Folder name is required\"),\n parent: z.string().optional()\n});\n\nconst ListFolderSchema = z.object({\n folderId: z.string().optional(),\n pageSize: z.number().int().min(1).max(100).optional(),\n pageToken: z.string().optional()\n});\n\nconst ListSharedDrivesSchema = z.object({\n pageSize: z.number().int().min(1).max(100).optional(),\n pageToken: z.string().optional()\n});\n\nconst DeleteItemSchema = z.object({\n itemId: z.string().min(1, \"Item ID is required\")\n});\n\nconst RenameItemSchema = z.object({\n itemId: z.string().min(1, \"Item ID is required\"),\n newName: z.string().min(1, \"New name is required\")\n});\n\nconst MoveItemSchema = z.object({\n itemId: z.string().min(1, \"Item ID is required\"),\n destinationFolderId: z.string().optional()\n});\n\nconst CopyFileSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\"),\n newName: z.string().optional(),\n parentFolderId: z.string().optional()\n});\n\nconst CreateShortcutSchema = z.object({\n targetFileId: z.string().min(1, \"Target file ID is required\"),\n parentFolderId: z.string().optional(),\n shortcutName: z.string().optional()\n});\n\nconst LockFileSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\"),\n reason: z.string().optional(),\n ownerRestricted: z.boolean().optional()\n});\n\nconst UnlockFileSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\")\n});\n\nconst UploadFileSchema = z.object({\n localPath: z.string().min(1, \"Local file path is required\"),\n name: z.string().optional(),\n parentFolderId: z.string().optional(),\n mimeType: z.string().optional(),\n convertToGoogleFormat: z.boolean().optional()\n});\n\nconst DownloadFileSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\"),\n localPath: z.string().min(1, \"Local file path is required\"),\n exportMimeType: z.string().optional(),\n overwrite: z.boolean().optional().default(false),\n});\n\nconst ListPermissionsSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\"),\n});\n\nconst AddPermissionSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\"),\n emailAddress: z.string().email(\"Valid email is required\"),\n role: z.enum([\"owner\", \"organizer\", \"fileOrganizer\", \"writer\", \"commenter\", \"reader\"]).default(\"reader\"),\n type: z.enum([\"user\", \"group\", \"domain\", \"anyone\"]).default(\"user\"),\n sendNotificationEmail: z.boolean().optional().default(false),\n emailMessage: z.string().optional(),\n});\n\nconst UpdatePermissionSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\"),\n permissionId: z.string().min(1, \"Permission ID is required\"),\n role: z.enum([\"owner\", \"organizer\", \"fileOrganizer\", \"writer\", \"commenter\", \"reader\"]),\n});\n\nconst RemovePermissionSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\"),\n permissionId: z.string().optional(),\n emailAddress: z.string().email(\"Valid email is required\").optional(),\n}).superRefine((data, ctx) => {\n if (!data.permissionId && !data.emailAddress) {\n ctx.addIssue({ code: z.ZodIssueCode.custom, message: \"Either permissionId or emailAddress is required\" });\n }\n});\n\nconst ShareFileSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\"),\n emailAddress: z.string().email(\"Valid email is required\"),\n role: z.enum([\"writer\", \"commenter\", \"reader\"]).default(\"reader\"),\n sendNotificationEmail: z.boolean().optional().default(true),\n emailMessage: z.string().optional(),\n});\n\nconst ConvertPdfToGoogleDocSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\"),\n newName: z.string().optional(),\n parentFolderId: z.string().optional(),\n});\n\nconst BulkConvertFolderPdfsSchema = z.object({\n folderId: z.string().min(1, \"Folder ID is required\"),\n maxResults: z.number().int().min(1).max(200).optional().default(100),\n continueOnError: z.boolean().optional().default(true),\n});\n\nconst UploadPdfWithSplitSchema = z.object({\n localPath: z.string().min(1, \"Local file path is required\"),\n split: z.boolean().optional().default(false),\n maxPagesPerChunk: z.number().int().min(1).max(500).optional(),\n parentFolderId: z.string().optional(),\n namePrefix: z.string().optional(),\n});\n\nasync function splitPdfIntoChunkFiles(localPath: string, maxPagesPerChunk: number): Promise<{ tempDir: string; files: string[] }> {\n const sourceBytes = await readFile(localPath);\n const source = await PDFDocument.load(sourceBytes);\n const pageCount = source.getPageCount();\n\n if (pageCount === 0) {\n throw new Error('PDF contains no pages.');\n }\n\n const tempDir = await mkdtemp(join(tmpdir(), 'gdrive-mcp-split-'));\n const files: string[] = [];\n\n for (let start = 0, part = 1; start < pageCount; start += maxPagesPerChunk, part++) {\n const end = Math.min(start + maxPagesPerChunk, pageCount);\n const chunkDoc = await PDFDocument.create();\n const pages = await chunkDoc.copyPages(source, Array.from({ length: end - start }, (_, i) => start + i));\n for (const page of pages) chunkDoc.addPage(page);\n\n const chunkBytes = await chunkDoc.save();\n const chunkPath = join(tempDir, `part-${part}.pdf`);\n await writeFile(chunkPath, chunkBytes);\n files.push(chunkPath);\n }\n\n return { tempDir, files };\n}\n\nconst GetRevisionsSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\"),\n pageSize: z.number().int().min(1).max(200).optional().default(50),\n pageToken: z.string().optional(),\n});\n\nconst RestoreRevisionSchema = z.object({\n fileId: z.string().min(1, \"File ID is required\"),\n revisionId: z.string().min(1, \"Revision ID is required\"),\n confirm: z.boolean().optional().default(false),\n});\n\nconst AuthTestFileAccessSchema = z.object({\n fileId: z.string().optional(),\n});\n\nfunction getGrantedScopesFromAuthClient(ctx: ToolContext): string[] {\n const scopeRaw = ctx.authClient?.credentials?.scope;\n if (!scopeRaw || typeof scopeRaw !== 'string') return [];\n return [...new Set(scopeRaw.split(' ').map((s: string) => s.trim()).filter(Boolean))];\n}\n\nfunction resolveScopeStatus(ctx: ToolContext): { requestedScopes: string[]; grantedScopes: string[]; missingScopes: string[] } {\n const requestedScopes = resolveOAuthScopes();\n const grantedScopes = getGrantedScopesFromAuthClient(ctx);\n const missingScopes = requestedScopes.filter((s) => !grantedScopes.includes(s));\n return { requestedScopes, grantedScopes, missingScopes };\n}\n\n// ---------------------------------------------------------------------------\n// Tool definitions\n// ---------------------------------------------------------------------------\n\nexport const toolDefinitions: ToolDefinition[] = [\n {\n name: \"search\",\n description: \"Search for files in Google Drive. Set rawQuery=true to pass a raw Google Drive API query supporting operators like modifiedTime, createdTime, mimeType, name contains, etc.\",\n inputSchema: {\n type: \"object\",\n properties: {\n query: { type: \"string\", description: \"Search query. When rawQuery=true, this is passed directly to the Google Drive API as the q parameter.\" },\n pageSize: { type: \"number\", description: \"Results per page (default 50, max 100)\" },\n pageToken: { type: \"string\", description: \"Token for next page of results\" },\n rawQuery: { type: \"boolean\", description: \"If true, pass query directly to Google Drive API without wrapping in fullText contains. Enables date filters, mimeType filters, etc.\" },\n },\n required: [\"query\"],\n },\n },\n {\n name: \"createTextFile\",\n description: \"Create a new text or markdown file\",\n inputSchema: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"File name (.txt or .md)\" },\n content: { type: \"string\", description: \"File content\" },\n parentFolderId: { type: \"string\", description: \"Parent folder ID\" }\n },\n required: [\"name\", \"content\"]\n }\n },\n {\n name: \"updateTextFile\",\n description: \"Update an existing text or markdown file\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"ID of the file to update\" },\n content: { type: \"string\", description: \"New file content\" },\n name: { type: \"string\", description: \"New name (.txt or .md)\" }\n },\n required: [\"fileId\", \"content\"]\n }\n },\n {\n name: \"createFolder\",\n description: \"Create a new folder in Google Drive\",\n inputSchema: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"Folder name\" },\n parent: { type: \"string\", description: \"Parent folder ID or path\" }\n },\n required: [\"name\"]\n }\n },\n {\n name: \"listFolder\",\n description: \"List contents of a folder (defaults to root)\",\n inputSchema: {\n type: \"object\",\n properties: {\n folderId: { type: \"string\", description: \"Folder ID\" },\n pageSize: { type: \"number\", description: \"Items to return (default 50, max 100)\" },\n pageToken: { type: \"string\", description: \"Token for next page\" }\n }\n }\n },\n {\n name: \"listSharedDrives\",\n description: \"List available Google Shared Drives\",\n inputSchema: {\n type: \"object\",\n properties: {\n pageSize: { type: \"number\", description: \"Drives to return (default 50, max 100)\" },\n pageToken: { type: \"string\", description: \"Token for next page\" }\n }\n }\n },\n {\n name: \"deleteItem\",\n description: \"Move a file or folder to trash (can be restored from Google Drive trash)\",\n inputSchema: {\n type: \"object\",\n properties: {\n itemId: { type: \"string\", description: \"ID of the item to delete\" }\n },\n required: [\"itemId\"]\n }\n },\n {\n name: \"renameItem\",\n description: \"Rename a file or folder\",\n inputSchema: {\n type: \"object\",\n properties: {\n itemId: { type: \"string\", description: \"ID of the item to rename\" },\n newName: { type: \"string\", description: \"New name\" }\n },\n required: [\"itemId\", \"newName\"]\n }\n },\n {\n name: \"moveItem\",\n description: \"Move a file or folder\",\n inputSchema: {\n type: \"object\",\n properties: {\n itemId: { type: \"string\", description: \"ID of the item to move\" },\n destinationFolderId: { type: \"string\", description: \"Destination folder ID\" }\n },\n required: [\"itemId\"]\n }\n },\n {\n name: \"copyFile\",\n description: \"Creates a copy of a Google Drive file or document\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"ID of the file to copy\" },\n newName: { type: \"string\", description: \"Name for the copied file. If not provided, will use 'Copy of [original name]'\" },\n parentFolderId: { type: \"string\", description: \"ID or path of the destination folder (defaults to same folder as original)\" }\n },\n required: [\"fileId\"]\n }\n },\n {\n name: \"uploadFile\",\n description: \"Upload a local file (any type: image, audio, video, PDF, etc.) to Google Drive\",\n inputSchema: {\n type: \"object\",\n properties: {\n localPath: { type: \"string\", description: \"Absolute path to the local file to upload\" },\n name: { type: \"string\", description: \"File name in Drive (defaults to local filename)\" },\n parentFolderId: { type: \"string\", description: \"Parent folder ID or path (e.g., '/Work/Projects'). Creates folders if needed. Defaults to root.\" },\n mimeType: { type: \"string\", description: \"MIME type (auto-detected from extension if omitted)\" },\n convertToGoogleFormat: { type: \"boolean\", description: \"Convert uploaded file to Google Workspace format (e.g., .docx to Google Doc, .xlsx to Google Sheet, .pptx to Google Slides). Defaults to false.\" }\n },\n required: [\"localPath\"]\n }\n },\n {\n name: \"downloadFile\",\n description: \"Download a Google Drive file to a local path. For Google Workspace files (Docs, Sheets, Slides, Drawings), exports to the specified format. For regular files, downloads as-is. Streams directly to disk.\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"Google Drive file ID\" },\n localPath: { type: \"string\", description: \"Absolute local path to save the file (must start with /). Can be a directory (filename auto-resolved from Drive metadata) or a full file path. Path is normalized before use.\" },\n exportMimeType: {\n type: \"string\",\n description: \"For Google Workspace files: MIME type to export as (e.g., 'application/pdf', 'text/csv'). Auto-detected from file extension if omitted. Ignored for non-Workspace files.\"\n },\n overwrite: {\n type: \"boolean\",\n description: \"Whether to overwrite if file already exists at localPath. When false (default), returns an error instead of replacing the file.\"\n }\n },\n required: [\"fileId\", \"localPath\"]\n }\n },\n {\n name: \"listPermissions\",\n description: \"List sharing permissions for a file\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"Google Drive file ID\" }\n },\n required: [\"fileId\"]\n }\n },\n {\n name: \"addPermission\",\n description: \"Add a sharing permission to a file\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"Google Drive file ID\" },\n emailAddress: { type: \"string\", description: \"Target user/group email\" },\n role: { type: \"string\", enum: [\"owner\", \"organizer\", \"fileOrganizer\", \"writer\", \"commenter\", \"reader\"], description: \"Permission role\" },\n type: { type: \"string\", enum: [\"user\", \"group\", \"domain\", \"anyone\"], description: \"Principal type\" },\n sendNotificationEmail: { type: \"boolean\", description: \"Send notification email\" },\n emailMessage: { type: \"string\", description: \"Custom message to include in the notification email. Ignored unless sendNotificationEmail is true.\" }\n },\n required: [\"fileId\", \"emailAddress\"]\n }\n },\n {\n name: \"updatePermission\",\n description: \"Update an existing permission role\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"Google Drive file ID\" },\n permissionId: { type: \"string\", description: \"Permission ID\" },\n role: { type: \"string\", enum: [\"owner\", \"organizer\", \"fileOrganizer\", \"writer\", \"commenter\", \"reader\"], description: \"New role\" }\n },\n required: [\"fileId\", \"permissionId\", \"role\"]\n }\n },\n {\n name: \"removePermission\",\n description: \"Remove a permission from a file (by permissionId or emailAddress)\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"Google Drive file ID\" },\n permissionId: { type: \"string\", description: \"Permission ID\" },\n emailAddress: { type: \"string\", description: \"User email (alternative to permissionId)\" }\n },\n required: [\"fileId\"]\n }\n },\n {\n name: \"shareFile\",\n description: \"Convenience wrapper to share a file with a user email\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"Google Drive file ID\" },\n emailAddress: { type: \"string\", description: \"User email\" },\n role: { type: \"string\", enum: [\"writer\", \"commenter\", \"reader\"], description: \"Access role\" },\n sendNotificationEmail: { type: \"boolean\", description: \"Send notification email\" },\n emailMessage: { type: \"string\", description: \"Custom message to include in the notification email. Ignored unless sendNotificationEmail is true.\" }\n },\n required: [\"fileId\", \"emailAddress\"]\n }\n },\n {\n name: \"convertPdfToGoogleDoc\",\n description: \"Convert an existing PDF in Drive into an editable Google Doc\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"PDF file ID in Google Drive\" },\n newName: { type: \"string\", description: \"Optional name for converted Doc\" },\n parentFolderId: { type: \"string\", description: \"Optional destination folder ID\" }\n },\n required: [\"fileId\"]\n }\n },\n {\n name: \"bulkConvertFolderPdfs\",\n description: \"Convert all PDFs in a folder into Google Docs and return per-file results\",\n inputSchema: {\n type: \"object\",\n properties: {\n folderId: { type: \"string\", description: \"Folder ID containing PDFs\" },\n maxResults: { type: \"number\", description: \"Maximum PDFs to process (1-200, default: 100)\" },\n continueOnError: { type: \"boolean\", description: \"Continue conversion when one file fails (default: true)\" }\n },\n required: [\"folderId\"]\n }\n },\n {\n name: \"uploadPdfWithSplit\",\n description: \"Upload PDF and optionally split into chunked parts (metadata split plan for now)\",\n inputSchema: {\n type: \"object\",\n properties: {\n localPath: { type: \"string\", description: \"Absolute path to local PDF\" },\n split: { type: \"boolean\", description: \"Enable split mode\" },\n maxPagesPerChunk: { type: \"number\", description: \"Target max pages per chunk (advisory metadata)\" },\n parentFolderId: { type: \"string\", description: \"Optional destination folder ID\" },\n namePrefix: { type: \"string\", description: \"Optional output name prefix\" }\n },\n required: [\"localPath\"]\n }\n },\n {\n name: \"getRevisions\",\n description: \"List revisions for a file\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"Google Drive file ID\" },\n pageSize: { type: \"number\", description: \"Max revisions to return (default 50, max 200)\" },\n pageToken: { type: \"string\", description: \"Page token for pagination\" }\n },\n required: [\"fileId\"]\n }\n },\n {\n name: \"restoreRevision\",\n description: \"Restore a file to a selected revision (creates a new head revision). Note: workspace files (Docs, Sheets, Slides) are restored via export/import and may lose some formatting.\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"Google Drive file ID\" },\n revisionId: { type: \"string\", description: \"Revision ID to restore\" },\n confirm: { type: \"boolean\", description: \"Safety flag. Must be true to execute restore.\" }\n },\n required: [\"fileId\", \"revisionId\"]\n }\n },\n {\n name: \"authGetStatus\",\n description: \"Show authentication/token status and scope diagnostics\",\n inputSchema: { type: \"object\", properties: {} }\n },\n {\n name: \"authListScopes\",\n description: \"List configured/requested scopes and currently granted scopes\",\n inputSchema: { type: \"object\", properties: {} }\n },\n {\n name: \"authTestFileAccess\",\n description: \"Run auth diagnostics against Drive API/file access\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: { type: \"string\", description: \"Optional file ID for targeted access check\" }\n }\n }\n },\n {\n name: \"createShortcut\",\n description: \"Create a shortcut (link) to a file or folder in Google Drive. Useful for referencing the same document from multiple locations without duplicating it.\",\n inputSchema: {\n type: \"object\",\n properties: {\n targetFileId: {\n type: \"string\",\n description: \"The file or folder ID (not a path) to create a shortcut to\"\n },\n parentFolderId: {\n type: \"string\",\n description: \"ID or path of the folder where the shortcut will be created\"\n },\n shortcutName: {\n type: \"string\",\n description: \"Custom name for the shortcut (defaults to original file name)\"\n }\n },\n required: [\"targetFileId\"]\n }\n },\n {\n name: \"lockFile\",\n description: \"Lock a file to prevent editing by setting content restrictions. The file remains readable but cannot be modified until unlocked.\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: {\n type: \"string\",\n description: \"ID of the file to lock\"\n },\n reason: {\n type: \"string\",\n description: \"Reason for locking the file (shown to users who try to edit)\"\n },\n ownerRestricted: {\n type: \"boolean\",\n description: \"If true, only the file owner can unlock the file (default: false)\"\n }\n },\n required: [\"fileId\"]\n }\n },\n {\n name: \"unlockFile\",\n description: \"Unlock a previously locked file by removing content restrictions, restoring full edit access.\",\n inputSchema: {\n type: \"object\",\n properties: {\n fileId: {\n type: \"string\",\n description: \"ID of the file to unlock\"\n }\n },\n required: [\"fileId\"]\n }\n },\n];\n\n// ---------------------------------------------------------------------------\n// Handler\n// ---------------------------------------------------------------------------\n\nexport async function handleTool(\n toolName: string,\n args: Record<string, unknown>,\n ctx: ToolContext,\n): Promise<ToolResult | null> {\n switch (toolName) {\n\n case \"search\": {\n const validation = SearchSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const { query: userQuery, pageSize, pageToken, rawQuery } = validation.data;\n\n let formattedQuery: string;\n if (rawQuery) {\n // Use query directly; auto-append trashed guard unless user already includes it\n formattedQuery = /\\btrashed\\s*=/.test(userQuery)\n ? userQuery\n : `${userQuery} and trashed = false`;\n } else {\n const escapedQuery = escapeDriveQuery(userQuery);\n formattedQuery = `fullText contains '${escapedQuery}' and trashed = false`;\n }\n\n const res = await ctx.getDrive().files.list({\n q: formattedQuery,\n pageSize: Math.min(pageSize || 50, 100),\n pageToken: pageToken,\n fields: \"nextPageToken, files(id, name, mimeType, createdTime, modifiedTime, size, parents)\",\n corpora: \"allDrives\",\n includeItemsFromAllDrives: true,\n supportsAllDrives: true\n });\n\n // Resolve folder paths from parent IDs (with dedup for concurrent lookups)\n const pathCache: Record<string, Promise<string>> = {};\n function resolveParentPath(folderId: string, depth = 0): Promise<string> {\n if (depth >= 10) return Promise.resolve(folderId);\n if (folderId in pathCache) return pathCache[folderId];\n const promise = (async () => {\n try {\n const folderRes = await ctx.getDrive().files.get({\n fileId: folderId,\n fields: \"name, parents\",\n supportsAllDrives: true,\n });\n const name = folderRes.data.name || folderId;\n const parents = folderRes.data.parents;\n if (parents && parents.length > 0 && parents[0] !== folderId) {\n const parentPath = await resolveParentPath(parents[0], depth + 1);\n return `${parentPath}/${name}`;\n }\n return name;\n } catch {\n return folderId;\n }\n })();\n pathCache[folderId] = promise;\n return promise;\n }\n\n const files = res.data.files || [];\n const fileLines = await Promise.all(\n files.map(async (f: drive_v3.Schema$File) => {\n let folderPath = '';\n if (f.parents && f.parents.length > 0) {\n folderPath = await resolveParentPath(f.parents[0]);\n }\n return `${f.name} (${f.mimeType}) [id: ${f.id}, path: ${folderPath || '/'}] [created: ${f.createdTime || 'N/A'}, modified: ${f.modifiedTime || 'N/A'}]`;\n }),\n );\n\n ctx.log('Search results', { query: userQuery, rawQuery: !!rawQuery, resultCount: files.length });\n\n let response = `Found ${files.length} files:\\n${fileLines.join(\"\\n\")}`;\n if (res.data.nextPageToken) {\n response += `\\n\\nMore results available. Use pageToken: ${res.data.nextPageToken}`;\n }\n\n return {\n content: [{ type: \"text\", text: response }],\n isError: false,\n };\n }\n\n case \"createTextFile\": {\n const validation = CreateTextFileSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const data = validation.data;\n\n ctx.validateTextFileExtension(data.name);\n const parentFolderId = await ctx.resolveFolderId(data.parentFolderId);\n\n // Check if file already exists\n const existingFileId = await ctx.checkFileExists(data.name, parentFolderId);\n if (existingFileId) {\n return errorResponse(\n `A file named \"${data.name}\" already exists in this location. ` +\n `To update it, use updateTextFile with fileId: ${existingFileId}`\n );\n }\n\n const fileMetadata = {\n name: data.name,\n mimeType: getMimeTypeFromFilename(data.name),\n parents: [parentFolderId]\n };\n\n const file = await ctx.getDrive().files.create({\n requestBody: fileMetadata,\n media: {\n mimeType: fileMetadata.mimeType,\n body: data.content,\n },\n supportsAllDrives: true\n });\n\n ctx.log('File created successfully', { fileId: file.data?.id });\n return {\n content: [{\n type: \"text\",\n text: `Created file: ${file.data?.name || data.name}\\nID: ${file.data?.id || 'unknown'}`\n }],\n isError: false\n };\n }\n\n case \"updateTextFile\": {\n const validation = UpdateTextFileSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const data = validation.data;\n\n // Check file MIME type\n const existingFile = await ctx.getDrive().files.get({\n fileId: data.fileId,\n fields: 'mimeType, name, parents',\n supportsAllDrives: true\n });\n\n const currentMimeType = existingFile.data.mimeType || 'text/plain';\n if (!Object.values(TEXT_MIME_TYPES).includes(currentMimeType)) {\n return errorResponse(\"File is not a text or markdown file.\");\n }\n\n const updateMetadata: { name?: string; mimeType?: string } = {};\n if (data.name) {\n ctx.validateTextFileExtension(data.name);\n updateMetadata.name = data.name;\n updateMetadata.mimeType = getMimeTypeFromFilename(data.name);\n }\n\n const updatedFile = await ctx.getDrive().files.update({\n fileId: data.fileId,\n requestBody: updateMetadata,\n media: {\n mimeType: updateMetadata.mimeType || currentMimeType,\n body: data.content\n },\n fields: 'id, name, modifiedTime, webViewLink',\n supportsAllDrives: true\n });\n\n return {\n content: [{\n type: \"text\",\n text: `Updated file: ${updatedFile.data.name}\\nModified: ${updatedFile.data.modifiedTime}`\n }],\n isError: false\n };\n }\n\n case \"createFolder\": {\n const validation = CreateFolderSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const data = validation.data;\n\n const parentFolderId = await ctx.resolveFolderId(data.parent);\n\n // Check if folder already exists\n const existingFolderId = await ctx.checkFileExists(data.name, parentFolderId);\n if (existingFolderId) {\n return errorResponse(\n `A folder named \"${data.name}\" already exists in this location. ` +\n `Folder ID: ${existingFolderId}`\n );\n }\n const folderMetadata = {\n name: data.name,\n mimeType: FOLDER_MIME_TYPE,\n parents: [parentFolderId]\n };\n\n const folder = await ctx.getDrive().files.create({\n requestBody: folderMetadata,\n fields: 'id, name, webViewLink',\n supportsAllDrives: true\n });\n\n ctx.log('Folder created successfully', { folderId: folder.data.id, name: folder.data.name });\n\n return {\n content: [{\n type: \"text\",\n text: `Created folder: ${folder.data.name}\\nID: ${folder.data.id}`\n }],\n isError: false\n };\n }\n\n case \"listFolder\": {\n const validation = ListFolderSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const data = validation.data;\n\n // Default to root if no folder specified\n const targetFolderId = data.folderId || 'root';\n\n const res = await ctx.getDrive().files.list({\n q: `'${targetFolderId}' in parents and trashed = false`,\n pageSize: Math.min(data.pageSize || 50, 100),\n pageToken: data.pageToken,\n fields: \"nextPageToken, files(id, name, mimeType, modifiedTime, size)\",\n orderBy: \"name\",\n includeItemsFromAllDrives: true,\n supportsAllDrives: true\n });\n\n const files = res.data.files || [];\n const formattedFiles = files.map((file: drive_v3.Schema$File) => {\n const isFolder = file.mimeType === FOLDER_MIME_TYPE;\n return `${isFolder ? '\uD83D\uDCC1' : '\uD83D\uDCC4'} ${file.name} (ID: ${file.id})`;\n }).join('\\n');\n\n let response = `Contents of folder:\\n\\n${formattedFiles}`;\n if (res.data.nextPageToken) {\n response += `\\n\\nMore items available. Use pageToken: ${res.data.nextPageToken}`;\n }\n\n return {\n content: [{ type: \"text\", text: response }],\n isError: false\n };\n }\n\n case \"listSharedDrives\": {\n const validation = ListSharedDrivesSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const data = validation.data;\n\n const res = await ctx.getDrive().drives.list({\n pageSize: Math.min(data.pageSize || 50, 100),\n pageToken: data.pageToken,\n fields: 'nextPageToken, drives(id, name, createdTime, hidden)'\n });\n\n const drives = res.data.drives || [];\n if (drives.length === 0) {\n return { content: [{ type: 'text', text: 'No shared drives found.' }], isError: false };\n }\n\n const formatted = drives\n .map((d: drive_v3.Schema$Drive) => `${d.name} (ID: ${d.id}${d.hidden ? ', hidden' : ''})`)\n .join('\\n');\n\n let response = `Found ${drives.length} shared drives:\\n${formatted}`;\n if (res.data.nextPageToken) {\n response += `\\n\\nMore results available. Use pageToken: ${res.data.nextPageToken}`;\n }\n\n return {\n content: [{ type: 'text', text: response }],\n isError: false,\n };\n }\n\n case \"deleteItem\": {\n const validation = DeleteItemSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const data = validation.data;\n\n const item = await ctx.getDrive().files.get({ fileId: data.itemId, fields: 'name', supportsAllDrives: true });\n\n // Move to trash instead of permanent deletion\n await ctx.getDrive().files.update({\n fileId: data.itemId,\n requestBody: {\n trashed: true\n },\n supportsAllDrives: true\n });\n\n ctx.log('Item moved to trash successfully', { itemId: data.itemId, name: item.data.name });\n return {\n content: [{ type: \"text\", text: `Successfully moved to trash: ${item.data.name}` }],\n isError: false\n };\n }\n\n case \"renameItem\": {\n const validation = RenameItemSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const data = validation.data;\n\n // If it's a text file, check extension\n const item = await ctx.getDrive().files.get({ fileId: data.itemId, fields: 'name, mimeType', supportsAllDrives: true });\n if (Object.values(TEXT_MIME_TYPES).includes(item.data.mimeType || '')) {\n ctx.validateTextFileExtension(data.newName);\n }\n\n const updatedItem = await ctx.getDrive().files.update({\n fileId: data.itemId,\n requestBody: { name: data.newName },\n fields: 'id, name, modifiedTime',\n supportsAllDrives: true\n });\n\n return {\n content: [{\n type: \"text\",\n text: `Successfully renamed \"${item.data.name}\" to \"${updatedItem.data.name}\"`\n }],\n isError: false\n };\n }\n\n case \"moveItem\": {\n const validation = MoveItemSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const data = validation.data;\n\n const destinationFolderId = data.destinationFolderId ?\n await ctx.resolveFolderId(data.destinationFolderId) :\n 'root';\n\n // Check we aren't moving a folder into itself or its descendant\n if (data.destinationFolderId === data.itemId) {\n return errorResponse(\"Cannot move a folder into itself.\");\n }\n\n const item = await ctx.getDrive().files.get({ fileId: data.itemId, fields: 'name, parents', supportsAllDrives: true });\n\n // Perform move\n await ctx.getDrive().files.update({\n fileId: data.itemId,\n addParents: destinationFolderId,\n removeParents: item.data.parents?.join(',') || '',\n fields: 'id, name, parents',\n supportsAllDrives: true\n });\n\n // Get the destination folder name for a nice response\n const destinationFolder = await ctx.getDrive().files.get({\n fileId: destinationFolderId,\n fields: 'name',\n supportsAllDrives: true\n });\n\n return {\n content: [{\n type: \"text\",\n text: `Successfully moved \"${item.data.name}\" to \"${destinationFolder.data.name}\"`\n }],\n isError: false\n };\n }\n\n case \"copyFile\": {\n const validation = CopyFileSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const data = validation.data;\n\n // Get original file info\n const originalFile = await ctx.getDrive().files.get({\n fileId: data.fileId,\n fields: 'name,parents',\n supportsAllDrives: true\n });\n\n const copyMetadata: any = {\n name: data.newName || `Copy of ${originalFile.data.name}`\n };\n\n if (data.parentFolderId) {\n const resolvedParentId = await ctx.resolveFolderId(data.parentFolderId);\n copyMetadata.parents = [resolvedParentId];\n } else if (originalFile.data.parents) {\n copyMetadata.parents = originalFile.data.parents;\n }\n\n const response = await ctx.getDrive().files.copy({\n fileId: data.fileId,\n requestBody: copyMetadata,\n fields: 'id,name,webViewLink,parents',\n supportsAllDrives: true\n });\n\n return {\n content: [{ type: \"text\", text: `Successfully copied file as \"${response.data.name}\"\\nNew file ID: ${response.data.id}\\nLink: ${response.data.webViewLink}` }],\n isError: false\n };\n }\n\n case \"createShortcut\": {\n const validation = CreateShortcutSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const data = validation.data;\n\n const parentId = await ctx.resolveFolderId(data.parentFolderId);\n\n // Get target file metadata for default name\n const targetFile = await ctx.getDrive().files.get({\n fileId: data.targetFileId,\n fields: 'id, name, mimeType',\n supportsAllDrives: true\n });\n\n const shortcutName = data.shortcutName || targetFile.data.name || 'Shortcut';\n\n const shortcut = await ctx.getDrive().files.create({\n requestBody: {\n name: shortcutName,\n mimeType: SHORTCUT_MIME_TYPE,\n shortcutDetails: {\n targetId: data.targetFileId\n },\n parents: [parentId]\n },\n fields: 'id, name, webViewLink, shortcutDetails',\n supportsAllDrives: true\n });\n\n ctx.log('Shortcut created', {\n shortcutId: shortcut.data.id,\n targetId: data.targetFileId,\n name: shortcutName\n });\n\n return {\n content: [{\n type: \"text\",\n text: `Shortcut created successfully!\\n\\nShortcut: ${shortcut.data.name} (${shortcut.data.id})\\nTarget: ${targetFile.data.name} (${data.targetFileId})\\nLocation: folder ${parentId}\\nLink: ${shortcut.data.webViewLink || 'N/A'}`\n }],\n isError: false\n };\n }\n\n case \"lockFile\": {\n const validation = LockFileSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const data = validation.data;\n\n const fileInfo = await ctx.getDrive().files.get({\n fileId: data.fileId,\n fields: 'id, name, contentRestrictions',\n supportsAllDrives: true\n });\n\n const existingRestrictions = fileInfo.data.contentRestrictions || [];\n if (existingRestrictions.some((r) => r.readOnly)) {\n return {\n content: [{\n type: \"text\",\n text: `File \"${fileInfo.data.name}\" is already locked.`\n }],\n isError: false\n };\n }\n\n await ctx.getDrive().files.update({\n fileId: data.fileId,\n requestBody: {\n contentRestrictions: [{\n readOnly: true,\n reason: data.reason || 'Locked via MCP',\n ownerRestricted: data.ownerRestricted ?? false\n }]\n },\n supportsAllDrives: true\n });\n\n ctx.log('File locked', { fileId: data.fileId, name: fileInfo.data.name, reason: data.reason });\n\n return {\n content: [{\n type: \"text\",\n text: `File locked successfully!\\n\\nFile: ${fileInfo.data.name}\\nReason: ${data.reason || 'Locked via MCP'}${data.ownerRestricted ? '\\nOwner-restricted: only the file owner can unlock' : ''}\\n\\nThe file is now read-only and cannot be edited or deleted.`\n }],\n isError: false\n };\n }\n\n case \"unlockFile\": {\n const validation = UnlockFileSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const data = validation.data;\n\n const fileInfo = await ctx.getDrive().files.get({\n fileId: data.fileId,\n fields: 'id, name, contentRestrictions',\n supportsAllDrives: true\n });\n\n const existingRestrictions = fileInfo.data.contentRestrictions || [];\n if (!existingRestrictions.some((r) => r.readOnly)) {\n return {\n content: [{\n type: \"text\",\n text: `File \"${fileInfo.data.name}\" is not locked.`\n }],\n isError: false\n };\n }\n\n await ctx.getDrive().files.update({\n fileId: data.fileId,\n requestBody: {\n contentRestrictions: [{ readOnly: false }]\n },\n supportsAllDrives: true\n });\n\n ctx.log('File unlocked', { fileId: data.fileId, name: fileInfo.data.name });\n\n return {\n content: [{\n type: \"text\",\n text: `File unlocked successfully!\\n\\nFile: ${fileInfo.data.name}\\n\\nThe file can now be edited and deleted.`\n }],\n isError: false\n };\n }\n\n case \"uploadFile\": {\n const validation = UploadFileSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const data = validation.data;\n\n // Validate local file exists\n if (!existsSync(data.localPath)) {\n return errorResponse(`File not found: ${data.localPath}`);\n }\n\n const stats = statSync(data.localPath);\n const fileName = data.name || data.localPath.split(/[\\\\/]/).pop() || 'upload';\n const ext = fileName.split('.').pop()?.toLowerCase() || '';\n const detectedMime = data.mimeType || BINARY_MIME_TYPES[ext] || 'application/octet-stream';\n const parentId = await ctx.resolveFolderId(data.parentFolderId);\n\n // Google Workspace conversion mapping\n const GOOGLE_FORMAT_MAP: Record<string, string> = {\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': 'application/vnd.google-apps.document',\n 'application/msword': 'application/vnd.google-apps.document',\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'application/vnd.google-apps.spreadsheet',\n 'application/vnd.ms-excel': 'application/vnd.google-apps.spreadsheet',\n 'application/vnd.openxmlformats-officedocument.presentationml.presentation': 'application/vnd.google-apps.presentation',\n 'application/vnd.ms-powerpoint': 'application/vnd.google-apps.presentation',\n };\n\n const targetMimeType = data.convertToGoogleFormat ? GOOGLE_FORMAT_MAP[detectedMime] : undefined;\n\n if (data.convertToGoogleFormat && !targetMimeType) {\n return errorResponse(\n `Cannot convert MIME type \"${detectedMime}\" to a Google Workspace format. ` +\n `Supported: .docx, .doc, .xlsx, .xls, .pptx, .ppt`\n );\n }\n\n const uploadName = targetMimeType ? fileName.replace(/\\.[^.]+$/, '') : fileName;\n\n ctx.log('Uploading file', { localPath: data.localPath, name: uploadName, mimeType: detectedMime, convertToGoogle: !!targetMimeType, size: stats.size });\n\n const requestBody: any = {\n name: uploadName,\n parents: [parentId]\n };\n if (targetMimeType) {\n requestBody.mimeType = targetMimeType;\n }\n\n const file = await ctx.getDrive().files.create({\n requestBody,\n media: {\n mimeType: detectedMime,\n body: createReadStream(data.localPath)\n },\n fields: 'id, name, size, mimeType, webViewLink',\n supportsAllDrives: true\n });\n\n ctx.log('File uploaded successfully', { fileId: file.data?.id });\n return {\n content: [{\n type: \"text\",\n text: [\n `Uploaded: ${file.data?.name || fileName}`,\n `ID: ${file.data?.id || 'unknown'}`,\n `Size: ${file.data?.size || stats.size} bytes`,\n `Type: ${file.data?.mimeType || detectedMime}`,\n file.data?.webViewLink ? `Link: ${file.data.webViewLink}` : ''\n ].filter(Boolean).join('\\n')\n }],\n isError: false\n };\n }\n\n case \"downloadFile\": {\n const validation = DownloadFileSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const data = validation.data;\n const downloadResult = await downloadDriveFile(ctx.getDrive(), data, ctx.log);\n\n return {\n content: [{\n type: 'text',\n text: [\n `Downloaded: ${downloadResult.driveName}`,\n `Saved to: ${downloadResult.resolvedPath}`,\n `Size: ${downloadResult.size} bytes`,\n downloadResult.isWorkspaceFile\n ? `Export format: ${downloadResult.exportMime}`\n : `Type: ${downloadResult.driveMimeType}`,\n ].join('\\n'),\n }],\n isError: false,\n };\n }\n\n case \"listPermissions\": {\n const validation = ListPermissionsSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const data = validation.data;\n\n const response = await ctx.getDrive().permissions.list({\n fileId: data.fileId,\n fields: 'permissions(id,type,role,emailAddress,domain,displayName,permissionDetails(inherited,inheritedFrom,permissionType))',\n supportsAllDrives: true,\n });\n\n const permissions = response.data.permissions || [];\n if (permissions.length === 0) {\n return { content: [{ type: 'text', text: 'No permissions found.' }], isError: false };\n }\n\n const lines = permissions.map((p) => {\n const who = p.emailAddress || p.domain || p.displayName || p.type || 'unknown';\n const inherited = p.permissionDetails?.some((d) => d.inherited === true) ?? false;\n const inheritedFrom = p.permissionDetails?.find((d) => d.inheritedFrom)?.inheritedFrom;\n const inheritedMarker = inherited\n ? ` [inherited${inheritedFrom ? ` from ${inheritedFrom}` : ''}]`\n : ' [direct]';\n return `- ${p.id}: ${who} (${p.type}) => ${p.role}${inheritedMarker}`;\n });\n\n return { content: [{ type: 'text', text: `Permissions for file ${data.fileId}:\\n${lines.join('\\n')}` }], isError: false };\n }\n\n case \"addPermission\": {\n const validation = AddPermissionSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const data = validation.data;\n\n const response = await ctx.getDrive().permissions.create({\n fileId: data.fileId,\n requestBody: {\n type: data.type,\n role: data.role,\n emailAddress: data.emailAddress,\n },\n sendNotificationEmail: data.sendNotificationEmail,\n ...(data.emailMessage && { emailMessage: data.emailMessage }),\n fields: 'id,type,role,emailAddress',\n supportsAllDrives: true,\n });\n\n return { content: [{ type: 'text', text: `Permission added: ${response.data.id} (${response.data.role}) for ${response.data.emailAddress || data.emailAddress}` }], isError: false };\n }\n\n case \"updatePermission\": {\n const validation = UpdatePermissionSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const data = validation.data;\n\n const response = await ctx.getDrive().permissions.update({\n fileId: data.fileId,\n permissionId: data.permissionId,\n requestBody: { role: data.role },\n fields: 'id,type,role,emailAddress',\n supportsAllDrives: true,\n });\n\n return { content: [{ type: 'text', text: `Permission updated: ${response.data.id} => ${response.data.role}` }], isError: false };\n }\n\n case \"removePermission\": {\n const validation = RemovePermissionSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const data = validation.data;\n\n let permissionId: string | undefined = data.permissionId;\n if (!permissionId && data.emailAddress) {\n const listed = await ctx.getDrive().permissions.list({\n fileId: data.fileId,\n fields: 'permissions(id,type,emailAddress)',\n supportsAllDrives: true,\n });\n const found = (listed.data.permissions || []).find(\n (p) => p.type === 'user' && (p.emailAddress || '').toLowerCase() === data.emailAddress!.toLowerCase(),\n );\n if (!found?.id) {\n return errorResponse(`No permission found for ${data.emailAddress}`);\n }\n permissionId = found.id;\n }\n\n if (!permissionId) {\n return errorResponse(\"Could not resolve a permission ID to remove\");\n }\n\n await ctx.getDrive().permissions.delete({\n fileId: data.fileId,\n permissionId,\n supportsAllDrives: true,\n });\n\n return { content: [{ type: 'text', text: `Permission removed: ${permissionId}` }], isError: false };\n }\n\n case \"shareFile\": {\n const validation = ShareFileSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const data = validation.data;\n\n // Idempotent behavior: update existing permission for the same principal instead of creating duplicates.\n const existing = await ctx.getDrive().permissions.list({\n fileId: data.fileId,\n fields: 'permissions(id,type,emailAddress,role)',\n supportsAllDrives: true,\n });\n\n const existingPerm = (existing.data.permissions || []).find(\n (p) => p.type === 'user' && (p.emailAddress || '').toLowerCase() === data.emailAddress.toLowerCase(),\n );\n\n if (existingPerm?.id) {\n if (existingPerm.role === data.role) {\n return {\n content: [{ type: 'text', text: `No changes needed: ${data.emailAddress} already has role ${data.role}. Permission ID: ${existingPerm.id}` }],\n isError: false,\n };\n }\n\n const updated = await ctx.getDrive().permissions.update({\n fileId: data.fileId,\n permissionId: existingPerm.id,\n requestBody: { role: data.role },\n fields: 'id,type,role,emailAddress',\n supportsAllDrives: true,\n });\n\n return {\n content: [{ type: 'text', text: `Updated existing permission for ${updated.data.emailAddress || data.emailAddress} to ${updated.data.role}. Permission ID: ${updated.data.id}` }],\n isError: false,\n };\n }\n\n const response = await ctx.getDrive().permissions.create({\n fileId: data.fileId,\n requestBody: {\n type: 'user',\n role: data.role,\n emailAddress: data.emailAddress,\n },\n sendNotificationEmail: data.sendNotificationEmail,\n ...(data.emailMessage && { emailMessage: data.emailMessage }),\n fields: 'id,type,role,emailAddress',\n supportsAllDrives: true,\n });\n\n return {\n content: [{ type: 'text', text: `Shared file with ${response.data.emailAddress || data.emailAddress} as ${response.data.role}. Permission ID: ${response.data.id}` }],\n isError: false,\n };\n }\n\n case \"convertPdfToGoogleDoc\": {\n const validation = ConvertPdfToGoogleDocSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const data = validation.data;\n\n const source = await ctx.getDrive().files.get({\n fileId: data.fileId,\n fields: 'id,name,mimeType,parents',\n supportsAllDrives: true,\n });\n\n if (source.data.mimeType !== 'application/pdf') {\n return errorResponse(`File ${data.fileId} is not a PDF (mimeType=${source.data.mimeType || 'unknown'})`);\n }\n\n const parentId = data.parentFolderId || source.data.parents?.[0];\n const converted = await ctx.getDrive().files.copy({\n fileId: data.fileId,\n requestBody: {\n name: data.newName || `${source.data.name || 'Converted PDF'} (Doc)`,\n mimeType: 'application/vnd.google-apps.document',\n ...(parentId ? { parents: [parentId] } : {}),\n },\n fields: 'id,name,webViewLink,mimeType',\n supportsAllDrives: true,\n });\n\n return { content: [{ type: 'text', text: `Converted PDF to Google Doc: ${converted.data.name}\\nID: ${converted.data.id}\\nLink: ${converted.data.webViewLink}` }], isError: false };\n }\n\n case \"bulkConvertFolderPdfs\": {\n const validation = BulkConvertFolderPdfsSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const data = validation.data;\n\n const list = await ctx.getDrive().files.list({\n q: `'${data.folderId}' in parents and mimeType='application/pdf' and trashed=false`,\n pageSize: data.maxResults,\n fields: 'files(id,name,mimeType)',\n includeItemsFromAllDrives: true,\n supportsAllDrives: true,\n });\n\n const files = list.data.files || [];\n const results: Array<{ id?: string; name?: string; docId?: string; ok: boolean; error?: string }> = [];\n\n // Sequential processing is intentional \u2014 parallel copies trigger Google API rate limits.\n for (const f of files) {\n try {\n const converted = await ctx.getDrive().files.copy({\n fileId: f.id!,\n requestBody: {\n name: `${f.name || 'Converted PDF'} (Doc)`,\n mimeType: 'application/vnd.google-apps.document',\n parents: [data.folderId],\n },\n fields: 'id,name',\n supportsAllDrives: true,\n });\n results.push({ id: f.id ?? undefined, name: f.name ?? undefined, docId: converted.data.id ?? undefined, ok: true });\n } catch (err: any) {\n const message = err?.message || 'Unknown conversion error';\n results.push({ id: f.id ?? undefined, name: f.name ?? undefined, ok: false, error: message });\n if (!data.continueOnError) break;\n }\n }\n\n const ok = results.filter(r => r.ok).length;\n const fail = results.length - ok;\n return {\n content: [{ type: 'text', text: `Bulk PDF conversion finished. Processed=${results.length}, Success=${ok}, Failed=${fail}\\n\\n${results.map(r => r.ok ? `\u2705 ${r.name} -> ${r.docId}` : `\u274C ${r.name}: ${r.error}`).join('\\n')}` }],\n isError: false,\n };\n }\n\n case \"uploadPdfWithSplit\": {\n const validation = UploadPdfWithSplitSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const data = validation.data;\n\n if (!existsSync(data.localPath)) return errorResponse(`File not found: ${data.localPath}`);\n const parentId = await ctx.resolveFolderId(data.parentFolderId);\n\n if (!data.split) {\n const fileName = data.namePrefix || basename(data.localPath) || 'upload.pdf';\n const uploaded = await ctx.getDrive().files.create({\n requestBody: { name: fileName, parents: [parentId] },\n media: { mimeType: 'application/pdf', body: createReadStream(data.localPath) },\n fields: 'id,name,webViewLink',\n supportsAllDrives: true,\n });\n\n return {\n content: [{ type: 'text', text: `Uploaded PDF without split: ${uploaded.data.name}\\nID: ${uploaded.data.id}` }],\n isError: false,\n };\n }\n\n const maxPagesPerChunk = data.maxPagesPerChunk ?? 25;\n const baseName = data.namePrefix || basename(data.localPath, extname(data.localPath));\n\n let tempDir: string | undefined;\n try {\n const splitResult = await splitPdfIntoChunkFiles(data.localPath, maxPagesPerChunk);\n tempDir = splitResult.tempDir;\n\n const uploadedParts: Array<{ id?: string | null; name?: string | null }> = [];\n for (let i = 0; i < splitResult.files.length; i++) {\n const partPath = splitResult.files[i];\n const partName = `${baseName}-part-${i + 1}.pdf`;\n\n const uploaded = await ctx.getDrive().files.create({\n requestBody: { name: partName, parents: [parentId] },\n media: { mimeType: 'application/pdf', body: createReadStream(partPath) },\n fields: 'id,name,webViewLink',\n supportsAllDrives: true,\n });\n\n uploadedParts.push({ id: uploaded.data.id, name: uploaded.data.name });\n }\n\n const lines = uploadedParts.map((p, idx) => `- part ${idx + 1}: ${p.name} (ID: ${p.id})`);\n return {\n content: [{\n type: 'text',\n text: `Uploaded split PDF into ${uploadedParts.length} part(s) using maxPagesPerChunk=${maxPagesPerChunk}\\n${lines.join('\\n')}`,\n }],\n isError: false,\n };\n } finally {\n if (tempDir) {\n await rm(tempDir, { recursive: true, force: true });\n }\n }\n }\n\n case \"getRevisions\": {\n const validation = GetRevisionsSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const data = validation.data;\n\n const response = await ctx.getDrive().revisions.list({\n fileId: data.fileId,\n pageSize: data.pageSize,\n pageToken: data.pageToken,\n fields: 'nextPageToken,revisions(id,modifiedTime,lastModifyingUser(displayName,emailAddress),keepForever,size,originalFilename)',\n });\n\n const revisions: drive_v3.Schema$Revision[] = response.data.revisions || [];\n if (revisions.length === 0) {\n return { content: [{ type: 'text', text: `No revisions found for file ${data.fileId}.` }], isError: false };\n }\n\n const lines = revisions.map((r: drive_v3.Schema$Revision) => {\n const who = r.lastModifyingUser?.displayName || r.lastModifyingUser?.emailAddress || 'unknown';\n return `- ${r.id}: ${r.modifiedTime || 'unknown-time'} by ${who}${r.keepForever ? ' [kept]' : ''}`;\n });\n\n let text = `Revisions for file ${data.fileId}:\\n${lines.join('\\n')}`;\n if (response.data.nextPageToken) {\n text += `\\n\\nMore revisions available. Use pageToken=\"${response.data.nextPageToken}\" to fetch the next page.`;\n }\n\n return {\n content: [{ type: 'text', text }],\n isError: false,\n };\n }\n\n case \"restoreRevision\": {\n const validation = RestoreRevisionSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const data = validation.data;\n\n if (!data.confirm) {\n return errorResponse('Refusing restore: set confirm=true to restore a revision.');\n }\n\n try {\n // Get current file metadata to determine restore strategy\n const current = await ctx.getDrive().files.get({\n fileId: data.fileId,\n fields: 'name,mimeType',\n supportsAllDrives: true,\n });\n\n const fileMimeType = current.data.mimeType || '';\n const isWorkspaceFile = fileMimeType.startsWith('application/vnd.google-apps.');\n\n let revisionBody: unknown;\n let uploadMimeType: string;\n\n if (isWorkspaceFile) {\n // Workspace files don't support revisions.get with alt=media.\n // Use the revision's exportLinks to fetch content in an editable format.\n const revision = await ctx.getDrive().revisions.get({\n fileId: data.fileId,\n revisionId: data.revisionId,\n fields: 'id,exportLinks',\n });\n\n const exportLinks = (revision.data.exportLinks as Record<string, string> | null) || {};\n\n // Build preference list: editable formats from GOOGLE_WORKSPACE_EXPORT_FORMATS, excluding pdf\n const formatMap = GOOGLE_WORKSPACE_EXPORT_FORMATS[fileMimeType];\n const editableMimes = formatMap\n ? Object.entries(formatMap).filter(([ext]) => ext !== 'pdf').map(([, mime]) => mime)\n : [];\n\n // Pick the first editable MIME type available in exportLinks\n const selectedMime = editableMimes.find((m) => exportLinks[m])\n || Object.keys(exportLinks).find((m) => m !== 'application/pdf')\n || Object.keys(exportLinks)[0];\n\n if (!selectedMime || !exportLinks[selectedMime]) {\n return errorResponse('Selected revision has no usable export links for restore.');\n }\n\n uploadMimeType = selectedMime;\n\n // Fetch revision content from the export link using authenticated request\n const exportResponse = await ctx.authClient.request({ url: exportLinks[selectedMime], responseType: 'stream' });\n revisionBody = exportResponse.data;\n } else {\n // For binary files, download the revision content directly\n const revision = await ctx.getDrive().revisions.get(\n { fileId: data.fileId, revisionId: data.revisionId, alt: 'media' },\n { responseType: 'stream' },\n );\n revisionBody = revision.data;\n uploadMimeType = fileMimeType || 'application/octet-stream';\n }\n\n await ctx.getDrive().files.update({\n fileId: data.fileId,\n media: {\n mimeType: uploadMimeType,\n body: revisionBody,\n },\n supportsAllDrives: true,\n });\n\n const restoreMsg = `Restored file ${data.fileId} (${current.data.name || 'unnamed'}) from revision ${data.revisionId}.`;\n const workspaceWarning = isWorkspaceFile\n ? '\\n\\nWarning: This workspace file was restored via export/import. Some formatting or features (e.g. comments, suggestions, version history metadata) may have been lost.'\n : '';\n\n return {\n content: [{\n type: 'text',\n text: restoreMsg + workspaceWarning,\n }],\n isError: false,\n };\n } catch (err: unknown) {\n return errorResponse(`Failed to restore revision: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n case \"authGetStatus\": {\n const tokenPath = getSecureTokenPath();\n const tokenFileExists = existsSync(tokenPath);\n let scopeStatus: ReturnType<typeof resolveScopeStatus>;\n try {\n scopeStatus = resolveScopeStatus(ctx);\n } catch (e: unknown) {\n return errorResponse(`Invalid scope configuration: ${e instanceof Error ? e.message : String(e)}`);\n }\n const { requestedScopes, grantedScopes, missingScopes } = scopeStatus;\n const expiryDate = ctx.authClient?.credentials?.expiry_date as number | undefined;\n const expiresInSec = expiryDate ? Math.floor((expiryDate - Date.now()) / 1000) : null;\n\n const payload = {\n tokenFilePath: tokenPath,\n tokenFileExists,\n hasAccessToken: !!ctx.authClient?.credentials?.access_token,\n hasRefreshToken: !!ctx.authClient?.credentials?.refresh_token,\n expiryDate: expiryDate || null,\n expiresInSec,\n requestedScopes,\n grantedScopes,\n missingScopes,\n };\n\n const status =\n !tokenFileExists || !payload.hasRefreshToken ? 'needs_reauth' :\n missingScopes.length > 0 ? 'scope_mismatch' :\n 'ok';\n\n let text = `Auth status (${status}):\\n${JSON.stringify(payload, null, 2)}\\n\\nSummary: token file ${tokenFileExists ? 'found' : 'missing'}, missing scopes=${missingScopes.length}.`;\n if (grantedScopes.length === 0 && payload.hasAccessToken) {\n text += '\\nNote: granted scopes may appear empty when the token was loaded from disk. This does not necessarily indicate missing permissions.';\n }\n\n return {\n content: [{ type: 'text', text }],\n isError: false,\n };\n }\n\n case \"authListScopes\": {\n let scopeStatus: ReturnType<typeof resolveScopeStatus>;\n try {\n scopeStatus = resolveScopeStatus(ctx);\n } catch (e: unknown) {\n return errorResponse(`Invalid scope configuration: ${e instanceof Error ? e.message : String(e)}`);\n }\n const { requestedScopes, grantedScopes, missingScopes } = scopeStatus;\n const presetsResolved = Object.fromEntries(\n Object.entries(SCOPE_PRESETS).map(([k, v]) => [k, v.map((s) => SCOPE_ALIASES[s] || s)]),\n );\n\n let text = `Scopes:\\n${JSON.stringify({ requestedScopes, grantedScopes, missingScopes, presets: presetsResolved }, null, 2)}`;\n if (grantedScopes.length === 0 && !!ctx.authClient?.credentials?.access_token) {\n text += '\\nNote: granted scopes may appear empty when the token was loaded from disk. This does not necessarily indicate missing permissions.';\n }\n\n return {\n content: [{ type: 'text', text }],\n isError: false,\n };\n }\n\n case \"authTestFileAccess\": {\n const validation = AuthTestFileAccessSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const data = validation.data;\n\n try {\n let check: { mode: string; [key: string]: unknown };\n if (data.fileId) {\n const file = await ctx.getDrive().files.get({\n fileId: data.fileId,\n fields: 'id,name,mimeType,permissions',\n supportsAllDrives: true,\n });\n check = { mode: 'file', fileId: file.data.id, name: file.data.name, mimeType: file.data.mimeType };\n } else {\n const list = await ctx.getDrive().files.list({\n pageSize: 1,\n fields: 'files(id,name,mimeType)',\n includeItemsFromAllDrives: true,\n supportsAllDrives: true,\n });\n check = { mode: 'list', visibleCount: list.data.files?.length || 0, sample: list.data.files?.[0] || null };\n }\n\n return {\n content: [{ type: 'text', text: `Auth access check OK:\\n${JSON.stringify(check, null, 2)}` }],\n isError: false,\n };\n } catch (e: unknown) {\n const message = e instanceof Error ? e.message : String(e);\n return {\n content: [{ type: 'text', text: `Auth access check failed:\\n${JSON.stringify({ message }, null, 2)}` }],\n isError: true,\n };\n }\n }\n\n default:\n return null;\n }\n}\n", "import { createWriteStream, existsSync, renameSync, statSync, unlinkSync } from 'fs';\nimport { basename, dirname, extname, isAbsolute, join, relative, resolve } from 'path';\nimport { pipeline } from 'stream/promises';\n\nexport const GOOGLE_WORKSPACE_EXPORT_FORMATS: Record<string, Record<string, string>> = {\n 'application/vnd.google-apps.document': {\n pdf: 'application/pdf',\n docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n md: 'text/markdown',\n txt: 'text/plain',\n html: 'text/html',\n rtf: 'application/rtf',\n odt: 'application/vnd.oasis.opendocument.text',\n epub: 'application/epub+zip',\n },\n 'application/vnd.google-apps.spreadsheet': {\n xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n csv: 'text/csv',\n pdf: 'application/pdf',\n ods: 'application/vnd.oasis.opendocument.spreadsheet',\n tsv: 'text/tab-separated-values',\n html: 'text/html',\n },\n 'application/vnd.google-apps.presentation': {\n pptx: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',\n pdf: 'application/pdf',\n txt: 'text/plain',\n odp: 'application/vnd.oasis.opendocument.presentation',\n },\n 'application/vnd.google-apps.drawing': {\n png: 'image/png',\n svg: 'image/svg+xml',\n pdf: 'application/pdf',\n jpg: 'image/jpeg',\n },\n};\n\nexport const GOOGLE_WORKSPACE_DEFAULT_EXPORT: Record<string, { mimeType: string; ext: string }> = {\n 'application/vnd.google-apps.document': { mimeType: 'application/pdf', ext: '.pdf' },\n 'application/vnd.google-apps.spreadsheet': { mimeType: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', ext: '.xlsx' },\n 'application/vnd.google-apps.presentation': { mimeType: 'application/vnd.openxmlformats-officedocument.presentationml.presentation', ext: '.pptx' },\n 'application/vnd.google-apps.drawing': { mimeType: 'image/png', ext: '.png' },\n};\n\nexport type DownloadFileArgs = {\n fileId: string;\n localPath: string;\n exportMimeType?: string;\n overwrite?: boolean;\n};\n\nexport type DownloadFileResult = {\n driveName: string;\n driveMimeType: string;\n exportMime?: string;\n isWorkspaceFile: boolean;\n resolvedPath: string;\n size: number;\n};\n\ntype DriveGetParams = {\n fileId: string;\n fields?: string;\n supportsAllDrives?: boolean;\n alt?: 'media';\n};\n\ntype DriveExportParams = {\n fileId: string;\n mimeType?: string;\n};\n\ntype DriveRequestOptions = {\n responseType?: 'stream';\n};\n\ntype DriveResponse = {\n data: any;\n};\n\ntype DriveLike = {\n files: {\n get: (params: DriveGetParams, options?: DriveRequestOptions) => Promise<DriveResponse>;\n export: (params: DriveExportParams, options?: DriveRequestOptions) => Promise<DriveResponse>;\n };\n};\n\nfunction sanitizeDriveFilename(driveName: string): string {\n return basename(driveName).replace(/^\\.+/, '') || 'download';\n}\n\nfunction isPathWithinDirectory(targetPath: string, directoryPath: string): boolean {\n const relativePath = relative(resolve(directoryPath), resolve(targetPath));\n return relativePath === '' || (!relativePath.startsWith('..') && !isAbsolute(relativePath));\n}\n\nfunction resolveWorkspaceExport(\n driveMimeType: string,\n args: DownloadFileArgs,\n resolvedPath: string,\n isDirectory: boolean,\n): { exportMime: string; fileExtForName: string } {\n const formatMap = GOOGLE_WORKSPACE_EXPORT_FORMATS[driveMimeType];\n if (!formatMap) {\n throw new Error(\n `Unsupported Google Workspace type for export: ${driveMimeType}. ` +\n 'Supported types: Document, Spreadsheet, Presentation, Drawing.'\n );\n }\n\n if (args.exportMimeType) {\n const validMimes = Object.values(formatMap);\n if (!validMimes.includes(args.exportMimeType)) {\n throw new Error(\n `Unsupported export format '${args.exportMimeType}' for ${driveMimeType}. ` +\n `Supported: ${Object.entries(formatMap).map(([ext, mime]) => `${mime} (.${ext})`).join(', ')}`\n );\n }\n\n const extForMime = Object.entries(formatMap).find(([, mime]) => mime === args.exportMimeType)?.[0] || 'bin';\n return { exportMime: args.exportMimeType, fileExtForName: `.${extForMime}` };\n }\n\n if (!isDirectory && extname(resolvedPath)) {\n const ext = extname(resolvedPath).slice(1).toLowerCase();\n if (formatMap[ext]) {\n return { exportMime: formatMap[ext], fileExtForName: `.${ext}` };\n }\n }\n\n const defaultExport = GOOGLE_WORKSPACE_DEFAULT_EXPORT[driveMimeType];\n return { exportMime: defaultExport.mimeType, fileExtForName: defaultExport.ext };\n}\n\nfunction buildTempPath(resolvedPath: string): string {\n const random = Math.random().toString(16).slice(2);\n return `${resolvedPath}.download-${Date.now()}-${random}.tmp`;\n}\n\nexport async function downloadDriveFile(\n drive: DriveLike,\n args: DownloadFileArgs,\n log: (message: string, data?: unknown) => void,\n): Promise<DownloadFileResult> {\n if (!isAbsolute(args.localPath)) {\n throw new Error('localPath must be an absolute path');\n }\n\n const normalizedLocalPath = resolve(args.localPath);\n\n const fileMeta = await drive.files.get({\n fileId: args.fileId,\n fields: 'id, name, mimeType, size',\n supportsAllDrives: true,\n });\n\n const driveMimeType = fileMeta.data.mimeType;\n const driveName = fileMeta.data.name || 'download';\n\n if (!driveMimeType) {\n throw new Error('File has no MIME type');\n }\n\n const isWorkspaceFile = driveMimeType.startsWith('application/vnd.google-apps');\n const overwrite = args.overwrite ?? false;\n\n let resolvedPath = normalizedLocalPath;\n let isDirectory = false;\n\n if (existsSync(resolvedPath)) {\n isDirectory = statSync(resolvedPath).isDirectory();\n } else {\n const parentDir = dirname(resolvedPath);\n if (!existsSync(parentDir)) {\n throw new Error(`Parent directory does not exist: ${parentDir}`);\n }\n }\n\n let exportMime: string | undefined;\n let fileExtForName = '';\n\n if (isWorkspaceFile) {\n const exportSelection = resolveWorkspaceExport(driveMimeType, args, resolvedPath, isDirectory);\n exportMime = exportSelection.exportMime;\n fileExtForName = exportSelection.fileExtForName;\n }\n\n if (isDirectory) {\n const safeName = sanitizeDriveFilename(driveName);\n let fileName = safeName;\n if (isWorkspaceFile) {\n const nameWithoutExt = safeName.replace(/\\.[^.]+$/, '');\n fileName = `${nameWithoutExt}${fileExtForName}`;\n }\n\n resolvedPath = join(resolvedPath, fileName);\n if (!isPathWithinDirectory(resolvedPath, normalizedLocalPath)) {\n throw new Error('Resolved file path escapes the target directory');\n }\n }\n\n const targetExists = existsSync(resolvedPath);\n if (targetExists && !overwrite) {\n throw new Error(`File already exists at ${resolvedPath}. Set overwrite: true to replace it.`);\n }\n\n log('Downloading file', {\n fileId: args.fileId,\n driveName,\n driveMimeType,\n isWorkspaceFile,\n exportMime,\n localPath: resolvedPath,\n });\n\n const response = isWorkspaceFile\n ? await drive.files.export({ fileId: args.fileId, mimeType: exportMime }, { responseType: 'stream' })\n : await drive.files.get({ fileId: args.fileId, alt: 'media', supportsAllDrives: true }, { responseType: 'stream' });\n\n const writePath = overwrite && targetExists ? buildTempPath(resolvedPath) : resolvedPath;\n const dest = createWriteStream(writePath);\n\n try {\n await pipeline(response.data, dest);\n if (writePath !== resolvedPath) {\n renameSync(writePath, resolvedPath);\n }\n } catch (downloadErr) {\n try {\n unlinkSync(writePath);\n } catch {\n // Ignore cleanup errors.\n }\n throw downloadErr;\n }\n\n const finalStats = statSync(resolvedPath);\n\n log('File downloaded successfully', {\n fileId: args.fileId,\n localPath: resolvedPath,\n size: finalStats.size,\n });\n\n return {\n driveName,\n driveMimeType,\n exportMime,\n isWorkspaceFile,\n resolvedPath,\n size: finalStats.size,\n };\n}\n", "import { z } from 'zod';\nimport JSZip from 'jszip';\nimport type { ToolDefinition, ToolContext, ToolResult } from '../types.js';\nimport { errorResponse } from '../types.js';\nimport { escapeDriveQuery } from '../utils.js';\nimport { uploadImageToDrive } from '../utils/driveImageUpload.js';\n\n// ---------------------------------------------------------------------------\n// Helper functions\n// ---------------------------------------------------------------------------\n\n// Pure helper \u2013 no context needed\nfunction hexToRgbColor(hex: string): { red: number; green: number; blue: number } | null {\n if (!hex) return null;\n let hexClean = hex.startsWith('#') ? hex.slice(1) : hex;\n\n if (hexClean.length === 3) {\n hexClean = hexClean[0] + hexClean[0] + hexClean[1] + hexClean[1] + hexClean[2] + hexClean[2];\n }\n if (hexClean.length !== 6) return null;\n const bigint = parseInt(hexClean, 16);\n if (isNaN(bigint)) return null;\n\n const r = ((bigint >> 16) & 255) / 255;\n const g = ((bigint >> 8) & 255) / 255;\n const b = (bigint & 255) / 255;\n\n return { red: r, green: g, blue: b };\n}\n\n// Inverse of hexToRgbColor \u2013 converts Google Docs API color object to hex string\nfunction rgbColorToHex(color: any): string | null {\n if (!color?.color?.rgbColor) return null;\n const rgb = color.color.rgbColor;\n const r = Math.round((rgb.red || 0) * 255);\n const g = Math.round((rgb.green || 0) * 255);\n const b = Math.round((rgb.blue || 0) * 255);\n return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;\n}\n\n// Helper to recursively collect all tabs with their nesting level\nfunction collectAllTabsWithLevel(tabs: any[], level: number = 0): Array<{ tab: any; level: number }> {\n const result: Array<{ tab: any; level: number }> = [];\n for (const tab of tabs) {\n result.push({ tab, level });\n if (tab.childTabs && tab.childTabs.length > 0) {\n result.push(...collectAllTabsWithLevel(tab.childTabs, level + 1));\n }\n }\n return result;\n}\n\n// Helper to recursively find a tab by ID in the tab tree\nfunction findTabById(tabs: any[], targetId: string): any | null {\n for (const tab of tabs) {\n if (tab.tabProperties?.tabId === targetId) {\n return tab;\n }\n if (tab.childTabs && tab.childTabs.length > 0) {\n const found = findTabById(tab.childTabs, targetId);\n if (found) return found;\n }\n }\n return null;\n}\n\n// Execute batch update for Google Docs\nasync function executeBatchUpdate(ctx: ToolContext, documentId: string, requests: any[]): Promise<any> {\n if (!requests || requests.length === 0) {\n return {};\n }\n\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n\n try {\n const response = await docs.documents.batchUpdate({\n documentId: documentId,\n requestBody: { requests },\n });\n return response.data;\n } catch (error: any) {\n ctx.log('Google Docs batchUpdate error:', error.message);\n if (error.code === 404) throw new Error(`Document not found (ID: ${documentId})`);\n if (error.code === 403) throw new Error(`Permission denied for document (ID: ${documentId})`);\n throw new Error(`Google Docs API Error: ${error.message}`);\n }\n}\n\n// Find text in a document and return the range indices\nasync function findTextRange(ctx: ToolContext, documentId: string, textToFind: string, instance: number = 1): Promise<{ startIndex: number; endIndex: number } | null> {\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n\n try {\n const res = await docs.documents.get({\n documentId,\n fields: 'body(content(paragraph(elements(startIndex,endIndex,textRun(content))),table,startIndex,endIndex))',\n });\n\n if (!res.data.body?.content) {\n return null;\n }\n\n // Collect all text segments with their positions\n let fullText = '';\n const segments: { text: string; start: number; end: number }[] = [];\n\n const collectTextFromContent = (content: any[]) => {\n content.forEach(element => {\n if (element.paragraph?.elements) {\n element.paragraph.elements.forEach((pe: any) => {\n if (pe.textRun?.content && pe.startIndex !== undefined && pe.endIndex !== undefined) {\n const text = pe.textRun.content;\n fullText += text;\n segments.push({ text, start: pe.startIndex, end: pe.endIndex });\n }\n });\n }\n\n // Handle tables recursively\n if (element.table?.tableRows) {\n element.table.tableRows.forEach((row: any) => {\n if (row.tableCells) {\n row.tableCells.forEach((cell: any) => {\n if (cell.content) {\n collectTextFromContent(cell.content);\n }\n });\n }\n });\n }\n });\n };\n\n collectTextFromContent(res.data.body.content);\n segments.sort((a, b) => a.start - b.start);\n\n // Find the specified instance\n let foundCount = 0;\n let searchStartIndex = 0;\n\n while (foundCount < instance) {\n const currentIndex = fullText.indexOf(textToFind, searchStartIndex);\n if (currentIndex === -1) break;\n\n foundCount++;\n\n if (foundCount === instance) {\n const targetStartInFullText = currentIndex;\n const targetEndInFullText = currentIndex + textToFind.length;\n let currentPosInFullText = 0;\n let startIndex = -1;\n let endIndex = -1;\n\n for (const seg of segments) {\n const segStartInFullText = currentPosInFullText;\n const segEndInFullText = segStartInFullText + seg.text.length;\n\n if (startIndex === -1 && targetStartInFullText >= segStartInFullText && targetStartInFullText < segEndInFullText) {\n startIndex = seg.start + (targetStartInFullText - segStartInFullText);\n }\n\n if (targetEndInFullText > segStartInFullText && targetEndInFullText <= segEndInFullText) {\n endIndex = seg.start + (targetEndInFullText - segStartInFullText);\n break;\n }\n\n currentPosInFullText = segEndInFullText;\n }\n\n if (startIndex !== -1 && endIndex !== -1) {\n return { startIndex, endIndex };\n }\n }\n\n searchStartIndex = currentIndex + 1;\n }\n\n return null;\n } catch (error: any) {\n ctx.log('Error finding text in document:', error.message);\n if (error.code === 404) throw new Error(`Document not found (ID: ${documentId})`);\n throw new Error(`Failed to search document: ${error.message}`);\n }\n}\n\n// Get paragraph range containing a specific index\nasync function getParagraphRange(ctx: ToolContext, documentId: string, indexWithin: number): Promise<{ startIndex: number; endIndex: number } | null> {\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n\n try {\n const res = await docs.documents.get({\n documentId,\n fields: 'body(content(startIndex,endIndex,paragraph,table))',\n });\n\n if (!res.data.body?.content) {\n return null;\n }\n\n const findParagraphInContent = (content: any[]): { startIndex: number; endIndex: number } | null => {\n for (const element of content) {\n if (element.startIndex !== undefined && element.endIndex !== undefined) {\n if (indexWithin >= element.startIndex && indexWithin < element.endIndex) {\n if (element.paragraph) {\n return { startIndex: element.startIndex, endIndex: element.endIndex };\n }\n\n // Check table cells recursively\n if (element.table?.tableRows) {\n for (const row of element.table.tableRows) {\n if (row.tableCells) {\n for (const cell of row.tableCells) {\n if (cell.content) {\n const result = findParagraphInContent(cell.content);\n if (result) return result;\n }\n }\n }\n }\n }\n }\n }\n }\n return null;\n };\n\n return findParagraphInContent(res.data.body.content);\n } catch (error: any) {\n ctx.log('Error getting paragraph range:', error.message);\n throw new Error(`Failed to find paragraph: ${error.message}`);\n }\n}\n\n// Pure helper \u2013 build text style update request\nfunction buildUpdateTextStyleRequest(\n startIndex: number,\n endIndex: number,\n style: {\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n strikethrough?: boolean;\n fontSize?: number;\n fontFamily?: string;\n foregroundColor?: string;\n backgroundColor?: string;\n linkUrl?: string;\n }\n): { request: any; fields: string[] } | null {\n const textStyle: any = {};\n const fieldsToUpdate: string[] = [];\n\n if (style.bold !== undefined) { textStyle.bold = style.bold; fieldsToUpdate.push('bold'); }\n if (style.italic !== undefined) { textStyle.italic = style.italic; fieldsToUpdate.push('italic'); }\n if (style.underline !== undefined) { textStyle.underline = style.underline; fieldsToUpdate.push('underline'); }\n if (style.strikethrough !== undefined) { textStyle.strikethrough = style.strikethrough; fieldsToUpdate.push('strikethrough'); }\n if (style.fontSize !== undefined) { textStyle.fontSize = { magnitude: style.fontSize, unit: 'PT' }; fieldsToUpdate.push('fontSize'); }\n if (style.fontFamily !== undefined) { textStyle.weightedFontFamily = { fontFamily: style.fontFamily }; fieldsToUpdate.push('weightedFontFamily'); }\n\n if (style.foregroundColor !== undefined) {\n const rgbColor = hexToRgbColor(style.foregroundColor);\n if (!rgbColor) throw new Error(`Invalid foreground hex color: ${style.foregroundColor}`);\n textStyle.foregroundColor = { color: { rgbColor } };\n fieldsToUpdate.push('foregroundColor');\n }\n\n if (style.backgroundColor !== undefined) {\n const rgbColor = hexToRgbColor(style.backgroundColor);\n if (!rgbColor) throw new Error(`Invalid background hex color: ${style.backgroundColor}`);\n textStyle.backgroundColor = { color: { rgbColor } };\n fieldsToUpdate.push('backgroundColor');\n }\n\n if (style.linkUrl !== undefined) {\n textStyle.link = { url: style.linkUrl };\n fieldsToUpdate.push('link');\n }\n\n if (fieldsToUpdate.length === 0) return null;\n\n return {\n request: {\n updateTextStyle: {\n range: { startIndex, endIndex },\n textStyle,\n fields: fieldsToUpdate.join(','),\n }\n },\n fields: fieldsToUpdate\n };\n}\n\n// Pure helper \u2013 build paragraph style update request\nfunction buildUpdateParagraphStyleRequest(\n startIndex: number,\n endIndex: number,\n style: {\n alignment?: 'START' | 'END' | 'CENTER' | 'JUSTIFIED';\n indentStart?: number;\n indentEnd?: number;\n spaceAbove?: number;\n spaceBelow?: number;\n namedStyleType?: string;\n keepWithNext?: boolean;\n }\n): { request: any; fields: string[] } | null {\n const paragraphStyle: any = {};\n const fieldsToUpdate: string[] = [];\n\n if (style.alignment !== undefined) { paragraphStyle.alignment = style.alignment; fieldsToUpdate.push('alignment'); }\n if (style.indentStart !== undefined) { paragraphStyle.indentStart = { magnitude: style.indentStart, unit: 'PT' }; fieldsToUpdate.push('indentStart'); }\n if (style.indentEnd !== undefined) { paragraphStyle.indentEnd = { magnitude: style.indentEnd, unit: 'PT' }; fieldsToUpdate.push('indentEnd'); }\n if (style.spaceAbove !== undefined) { paragraphStyle.spaceAbove = { magnitude: style.spaceAbove, unit: 'PT' }; fieldsToUpdate.push('spaceAbove'); }\n if (style.spaceBelow !== undefined) { paragraphStyle.spaceBelow = { magnitude: style.spaceBelow, unit: 'PT' }; fieldsToUpdate.push('spaceBelow'); }\n if (style.namedStyleType !== undefined) { paragraphStyle.namedStyleType = style.namedStyleType; fieldsToUpdate.push('namedStyleType'); }\n if (style.keepWithNext !== undefined) { paragraphStyle.keepWithNext = style.keepWithNext; fieldsToUpdate.push('keepWithNext'); }\n\n if (fieldsToUpdate.length === 0) return null;\n\n return {\n request: {\n updateParagraphStyle: {\n range: { startIndex, endIndex },\n paragraphStyle,\n fields: fieldsToUpdate.join(','),\n }\n },\n fields: fieldsToUpdate\n };\n}\n\n// Insert an inline image from a URL\nasync function insertInlineImageHelper(\n ctx: ToolContext,\n documentId: string,\n imageUrl: string,\n index: number,\n width?: number,\n height?: number\n): Promise<any> {\n // Validate URL format\n try {\n new URL(imageUrl);\n } catch (_e) {\n throw new Error(`Invalid image URL format: ${imageUrl}`);\n }\n\n const request: any = {\n insertInlineImage: {\n location: { index },\n uri: imageUrl\n }\n };\n\n if (width && height) {\n request.insertInlineImage.objectSize = {\n height: { magnitude: height, unit: 'PT' },\n width: { magnitude: width, unit: 'PT' }\n };\n }\n\n return executeBatchUpdate(ctx, documentId, [request]);\n}\n\n// Image upload moved to ../utils/driveImageUpload.ts.\n\n// ---------------------------------------------------------------------------\n// Comment context extraction helpers\n// ---------------------------------------------------------------------------\n\n/** Context extracted for a single comment (keyed by Drive API comment ID) */\nexport interface CommentContext {\n contextBefore?: string;\n contextAfter?: string;\n startIndex?: number;\n endIndex?: number;\n}\n\n/** A segment of text with its Docs API startIndex */\ninterface TextSegment {\n text: string;\n startIndex: number;\n}\n\n/** Result of building flat text from a Google Doc */\ninterface FlatTextResult {\n flatText: string;\n offsetMap: number[];\n}\n\n// Guard against matching XML elements from distant/unrelated tables or paragraphs\nconst MAX_ROW_XML_DISTANCE = 100_000;\nconst MAX_PARAGRAPH_XML_DISTANCE = 50_000;\nconst MAX_PARAGRAPH_CONTEXT_LENGTH = 300;\n\n/**\n * Build flat text from a Google Doc, tracking each character's Docs API startIndex.\n * Handles paragraphs, tables (including nested), and multi-tab docs.\n */\nexport function buildFlatTextFromDoc(docData: any): FlatTextResult {\n function extractSegments(bodyContent: any[]): TextSegment[] {\n const segs: TextSegment[] = [];\n function fromElements(elements: any[]) {\n for (const el of elements) {\n if (el.textRun?.content && el.startIndex != null) {\n segs.push({ text: el.textRun.content, startIndex: el.startIndex });\n }\n }\n }\n for (const el of bodyContent) {\n if (el.paragraph?.elements) {\n fromElements(el.paragraph.elements);\n } else if (el.table) {\n for (const row of el.table.tableRows || []) {\n for (const cell of row.tableCells || []) {\n for (const cc of cell.content || []) {\n if (cc.paragraph?.elements) fromElements(cc.paragraph.elements);\n if (cc.table) {\n const nested = extractSegments([cc]);\n segs.push(...nested);\n }\n }\n }\n }\n }\n }\n return segs;\n }\n\n const allSegments: TextSegment[] = [];\n const tabs = (docData as any).tabs as any[] | undefined;\n if (tabs && tabs.length > 0) {\n for (const tab of tabs) {\n const bc = tab.documentTab?.body?.content;\n if (bc) allSegments.push(...extractSegments(bc));\n }\n } else if (docData.body?.content) {\n allSegments.push(...extractSegments(docData.body.content));\n }\n\n let flatText = '';\n const offsetMap: number[] = [];\n for (const seg of allSegments) {\n for (let i = 0; i < seg.text.length; i++) {\n offsetMap.push(seg.startIndex + i);\n flatText += seg.text[i];\n }\n }\n\n return { flatText, offsetMap };\n}\n\n/** Extract cell texts from a DOCX table row XML string */\nexport function extractRowCells(rowXml: string): string[] {\n const cells: string[] = [];\n let searchFrom = 0;\n while (true) {\n const tcStart1 = rowXml.indexOf('<w:tc>', searchFrom);\n const tcStart2 = rowXml.indexOf('<w:tc ', searchFrom);\n const tcStart = (tcStart1 === -1 && tcStart2 === -1) ? -1 :\n (tcStart1 === -1) ? tcStart2 : (tcStart2 === -1) ? tcStart1 : Math.min(tcStart1, tcStart2);\n if (tcStart === -1) break;\n const tcEnd = rowXml.indexOf('</w:tc>', tcStart);\n if (tcEnd === -1) break;\n const cellXml = rowXml.substring(tcStart, tcEnd);\n const tTexts: string[] = [];\n const tRegex = /<w:t[^>]*>([^<]*)<\\/w:t>/g;\n let t: RegExpExecArray | null;\n while ((t = tRegex.exec(cellXml)) !== null) tTexts.push(t[1]);\n if (tTexts.length > 0) cells.push(tTexts.join(''));\n searchFrom = tcEnd + 7;\n }\n return cells;\n}\n\n/** DOCX comment info parsed from word/comments.xml */\nexport interface DocxComment {\n author: string;\n date: string;\n content: string;\n}\n\n/** Context extracted from DOCX comment ranges in document.xml */\nexport interface DocxContextResult {\n docxComments: Map<number, DocxComment>;\n contextsBefore: Map<number, string>;\n contextsAfter: Map<number, string>;\n rowCells: Map<number, string[]>;\n}\n\n/**\n * Parse a DOCX export to extract comment positions and surrounding context.\n * Returns DOCX comment metadata and context maps keyed by DOCX comment ID.\n */\nexport async function resolveContextFromDocx(docxData: ArrayBuffer): Promise<DocxContextResult | null> {\n const zip = await JSZip.loadAsync(docxData);\n const commentsXml = await zip.file('word/comments.xml')?.async('string');\n const documentXml = await zip.file('word/document.xml')?.async('string');\n\n if (!commentsXml || !documentXml) return null;\n\n // \u2500\u2500 Parse word/comments.xml \u2500\u2500\n const docxComments = new Map<number, DocxComment>();\n const commentTagRegex = /<w:comment\\s+[^>]*?w:id=\"(\\d+)\"[^>]*>/g;\n let cMatch: RegExpExecArray | null;\n while ((cMatch = commentTagRegex.exec(commentsXml)) !== null) {\n const id = parseInt(cMatch[1]);\n const tagStr = cMatch[0];\n const authorMatch = tagStr.match(/w:author=\"([^\"]*)\"/);\n const dateMatch = tagStr.match(/w:date=\"([^\"]*)\"/);\n const author = authorMatch ? authorMatch[1] : '';\n const date = dateMatch ? dateMatch[1] : '';\n\n const endPos = commentsXml.indexOf('</w:comment>', cMatch.index);\n if (endPos !== -1) {\n const body = commentsXml.substring(cMatch.index, endPos);\n const texts: string[] = [];\n const tRegex = /<w:t[^>]*>([^<]*)<\\/w:t>/g;\n let tMatch: RegExpExecArray | null;\n while ((tMatch = tRegex.exec(body)) !== null) {\n texts.push(tMatch[1]);\n }\n docxComments.set(id, { author, date, content: texts.join('') });\n }\n }\n\n // \u2500\u2500 Parse document.xml for comment range context \u2500\u2500\n const contextsBefore = new Map<number, string>();\n const contextsAfter = new Map<number, string>();\n const rowCells = new Map<number, string[]>();\n\n const rangeStartRegex = /<w:commentRangeStart\\s+w:id=\"(\\d+)\"\\/>/g;\n let rMatch: RegExpExecArray | null;\n while ((rMatch = rangeStartRegex.exec(documentXml)) !== null) {\n const docxId = parseInt(rMatch[1]);\n const startPos = rMatch.index;\n\n // Try table row context first (most comments in table-based docs)\n const trStart = documentXml.lastIndexOf('<w:tr>', startPos);\n const trEnd = documentXml.indexOf('</w:tr>', startPos);\n if (trStart !== -1 && trEnd !== -1 && (startPos - trStart) < MAX_ROW_XML_DISTANCE) {\n const rowXml = documentXml.substring(trStart, trEnd);\n\n const cellTexts = extractRowCells(rowXml);\n // Find which cell contains the comment marker\n const commentMarker = `commentRangeStart w:id=\"${docxId}\"`;\n let commentCellIdx = -1;\n let cellSearchFrom = 0;\n for (let ci = 0; ci < cellTexts.length; ci++) {\n // Walk through <w:tc> tags in order to match cell index with extractRowCells output\n const tcStart1 = rowXml.indexOf('<w:tc>', cellSearchFrom);\n const tcStart2 = rowXml.indexOf('<w:tc ', cellSearchFrom);\n const tcStart = (tcStart1 === -1 && tcStart2 === -1) ? -1 :\n (tcStart1 === -1) ? tcStart2 : (tcStart2 === -1) ? tcStart1 : Math.min(tcStart1, tcStart2);\n if (tcStart === -1) break;\n const tcEnd = rowXml.indexOf('</w:tc>', tcStart);\n if (tcEnd === -1) break;\n const cellXml = rowXml.substring(tcStart, tcEnd);\n if (cellXml.includes(commentMarker)) {\n commentCellIdx = ci;\n }\n cellSearchFrom = tcEnd + 7;\n }\n\n if (cellTexts.length > 0) {\n const allTexts = cellTexts;\n rowCells.set(docxId, allTexts);\n\n if (commentCellIdx !== -1) {\n const before = cellTexts.slice(0, commentCellIdx);\n let after = cellTexts.slice(commentCellIdx + 1);\n\n // If comment is in the last cell, grab the NEXT row for \"after\" context\n if (commentCellIdx === cellTexts.length - 1) {\n const nextTrStart = documentXml.indexOf('<w:tr>', trEnd);\n const nextTrEnd = nextTrStart !== -1 ? documentXml.indexOf('</w:tr>', nextTrStart) : -1;\n if (nextTrStart !== -1 && nextTrEnd !== -1) {\n const nextRowXml = documentXml.substring(nextTrStart, nextTrEnd);\n after = extractRowCells(nextRowXml);\n }\n }\n\n const commentText = cellTexts[commentCellIdx];\n contextsBefore.set(docxId, [...before, commentText].join(' | '));\n contextsAfter.set(docxId, [commentText, ...after].join(' | '));\n } else {\n contextsBefore.set(docxId, allTexts.join(' | '));\n contextsAfter.set(docxId, '');\n }\n continue;\n }\n }\n\n // Paragraph fallback for non-table docs\n const pStart = documentXml.lastIndexOf('<w:p ', startPos);\n const pEnd = documentXml.indexOf('</w:p>', startPos);\n if (pStart !== -1 && pEnd !== -1 && (startPos - pStart) < MAX_PARAGRAPH_XML_DISTANCE) {\n const pXml = documentXml.substring(pStart, pEnd);\n const pTexts: string[] = [];\n const tRegex = /<w:t[^>]*>([^<]*)<\\/w:t>/g;\n let t: RegExpExecArray | null;\n while ((t = tRegex.exec(pXml)) !== null) pTexts.push(t[1]);\n const pText = pTexts.join('').trim();\n if (pText) {\n contextsBefore.set(docxId, pText.length > MAX_PARAGRAPH_CONTEXT_LENGTH\n ? pText.substring(0, MAX_PARAGRAPH_CONTEXT_LENGTH) + '...' : pText);\n contextsAfter.set(docxId, '');\n }\n }\n }\n\n return { docxComments, contextsBefore, contextsAfter, rowCells };\n}\n\n/**\n * Match Drive API comments to DOCX comments by (author, createdTime).\n * DOCX timestamps omit milliseconds, so we strip them from the API date.\n * Populates the contextMap with matched context. Also resolves Docs API\n * character offsets when flatText/offsetMap are available.\n */\nexport function matchDocxToDriveComments(\n driveComments: any[],\n docxResult: DocxContextResult,\n contextMap: Map<string, CommentContext>,\n flatText: string,\n offsetMap: number[],\n): void {\n const { docxComments, contextsBefore, contextsAfter } = docxResult;\n\n for (const comment of driveComments) {\n if (contextMap.has(comment.id)) continue; // already has Tier 1 context\n if (comment.resolved) continue; // resolved comments not in DOCX\n\n const apiAuthor = comment.author?.displayName || '';\n const apiDate = (comment.createdTime || '').replace(/\\.\\d+Z$/, 'Z');\n\n // Find matching DOCX comment\n let matchedDocxId: number | null = null;\n for (const [docxId, docxComment] of docxComments) {\n if (docxComment.author === apiAuthor && docxComment.date === apiDate) {\n matchedDocxId = docxId;\n break;\n }\n }\n\n if (matchedDocxId !== null) {\n const ctxBefore = contextsBefore.get(matchedDocxId) || '';\n const ctxAfter = contextsAfter.get(matchedDocxId) || '';\n if (ctxBefore || ctxAfter) {\n const entry: CommentContext = {\n contextBefore: ctxBefore,\n contextAfter: ctxAfter,\n };\n\n // Find Docs API character index using row context in flatText\n const quoted = comment.quotedFileContent?.value;\n if (quoted && flatText && offsetMap.length > 0 && ctxBefore) {\n const beforePattern = ctxBefore.split(' | ').join('\\n');\n\n const findAll = (pattern: string): number[] => {\n const results: number[] = [];\n let from = 0;\n while (true) {\n const idx = flatText.indexOf(pattern, from);\n if (idx === -1) break;\n results.push(idx);\n from = idx + 1;\n }\n return results;\n };\n\n let matches = findAll(beforePattern);\n\n if (matches.length !== 1 && ctxAfter) {\n const afterCells = ctxAfter.split(' | ');\n const afterWithoutAnchor = afterCells.slice(1).join('\\n');\n if (afterWithoutAnchor) {\n const fullPattern = beforePattern + '\\n' + afterWithoutAnchor;\n matches = findAll(fullPattern);\n }\n }\n\n if (matches.length === 1) {\n const patternStart = matches[0];\n const qIdx = patternStart + beforePattern.length - quoted.length;\n const endIdx = qIdx + quoted.length - 1;\n if (endIdx < offsetMap.length && flatText.substring(qIdx, qIdx + quoted.length) === quoted) {\n entry.startIndex = offsetMap[qIdx];\n entry.endIndex = offsetMap[endIdx] + 1;\n }\n }\n }\n\n contextMap.set(comment.id, entry);\n }\n // Remove from map so duplicate timestamps (rare) don't double-match\n docxComments.delete(matchedDocxId);\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Zod schemas\n// ---------------------------------------------------------------------------\n\nconst CreateGoogleDocSchema = z.object({\n name: z.string().min(1, \"Document name is required\"),\n content: z.string(),\n parentFolderId: z.string().optional()\n});\n\nconst UpdateGoogleDocSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n content: z.string(),\n tabId: z.string().optional()\n});\n\nconst GetGoogleDocContentSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n includeFormatting: z.boolean().optional(),\n});\n\nconst InsertTextSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n text: z.string().min(1, \"Text to insert is required\"),\n index: z.number().int().min(1, \"Index must be at least 1 (1-based)\"),\n tabId: z.string().optional()\n});\n\nconst DeleteRangeSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n startIndex: z.number().int().min(1, \"Start index must be at least 1\"),\n endIndex: z.number().int().min(1, \"End index must be at least 1\"),\n tabId: z.string().optional()\n}).refine(data => data.endIndex > data.startIndex, {\n message: \"End index must be greater than start index\",\n path: [\"endIndex\"]\n});\n\nconst ReadGoogleDocSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n format: z.enum(['text', 'json', 'markdown']).optional().default('text'),\n maxLength: z.number().int().min(1).optional(),\n tabId: z.string().optional()\n});\n\nconst ListDocumentTabsSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n includeContent: z.boolean().optional().default(false)\n});\n\nconst ApplyTextStyleSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n startIndex: z.number().int().min(1).optional(),\n endIndex: z.number().int().min(1).optional(),\n textToFind: z.string().min(1).optional(),\n matchInstance: z.number().int().min(1).optional().default(1),\n bold: z.boolean().optional(),\n italic: z.boolean().optional(),\n underline: z.boolean().optional(),\n strikethrough: z.boolean().optional(),\n fontSize: z.number().min(1).optional(),\n fontFamily: z.string().optional(),\n foregroundColor: z.string().optional(),\n backgroundColor: z.string().optional(),\n linkUrl: z.string().url().optional()\n});\n\nconst ApplyParagraphStyleSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n startIndex: z.number().int().min(1).optional(),\n endIndex: z.number().int().min(1).optional(),\n textToFind: z.string().min(1).optional(),\n matchInstance: z.number().int().min(1).optional().default(1),\n indexWithinParagraph: z.number().int().min(1).optional(),\n alignment: z.enum(['START', 'END', 'CENTER', 'JUSTIFIED']).optional(),\n indentStart: z.number().min(0).optional(),\n indentEnd: z.number().min(0).optional(),\n spaceAbove: z.number().min(0).optional(),\n spaceBelow: z.number().min(0).optional(),\n namedStyleType: z.enum(['NORMAL_TEXT', 'TITLE', 'SUBTITLE', 'HEADING_1', 'HEADING_2', 'HEADING_3', 'HEADING_4', 'HEADING_5', 'HEADING_6']).optional(),\n keepWithNext: z.boolean().optional()\n});\n\nconst CreateParagraphBulletsSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n startIndex: z.number().int().min(1).optional(),\n endIndex: z.number().int().min(1).optional(),\n textToFind: z.string().min(1).optional(),\n matchInstance: z.number().int().min(1).optional().default(1),\n bulletPreset: z.enum([\n 'BULLET_DISC_CIRCLE_SQUARE',\n 'BULLET_DIAMONDX_ARROW3D_SQUARE',\n 'BULLET_CHECKBOX',\n 'BULLET_ARROW_DIAMOND_DISC',\n 'BULLET_STAR_CIRCLE_SQUARE',\n 'BULLET_ARROW3D_CIRCLE_SQUARE',\n 'BULLET_LEFTTRIANGLE_DIAMOND_DISC',\n 'NUMBERED_DECIMAL_ALPHA_ROMAN',\n 'NUMBERED_DECIMAL_ALPHA_ROMAN_PARENS',\n 'NUMBERED_DECIMAL_NESTED',\n 'NUMBERED_UPPERALPHA_ALPHA_ROMAN',\n 'NUMBERED_UPPERROMAN_UPPERALPHA_DECIMAL',\n 'NUMBERED_ZERODECIMAL_ALPHA_ROMAN',\n 'NONE'\n ]).default('BULLET_DISC_CIRCLE_SQUARE')\n});\n\nconst ListCommentsSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n includeDeleted: z.boolean().optional(),\n pageSize: z.number().int().min(1).max(100).optional(),\n pageToken: z.string().optional(),\n});\n\nconst GetCommentSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n commentId: z.string().min(1, \"Comment ID is required\")\n});\n\nconst AddCommentSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n startIndex: z.number().int().min(1, \"Start index must be at least 1\"),\n endIndex: z.number().int().min(1, \"End index must be at least 1\"),\n commentText: z.string().min(1, \"Comment text is required\")\n});\n\nconst ReplyToCommentSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n commentId: z.string().min(1, \"Comment ID is required\"),\n replyText: z.string().min(1, \"Reply text is required\"),\n resolve: z.boolean().optional().describe(\"Set to true to resolve the comment thread after replying\")\n});\n\nconst DeleteCommentSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n commentId: z.string().min(1, \"Comment ID is required\")\n});\n\nconst InsertTableSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n rows: z.number().int().min(1, \"Must have at least 1 row\"),\n columns: z.number().int().min(1, \"Must have at least 1 column\"),\n index: z.number().int().min(1, \"Index must be at least 1 (1-based)\")\n});\n\nconst EditTableCellSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n tableStartIndex: z.number().int().min(1, \"Table start index is required\"),\n rowIndex: z.number().int().min(0, \"Row index must be at least 0 (0-based)\"),\n columnIndex: z.number().int().min(0, \"Column index must be at least 0 (0-based)\"),\n textContent: z.string().optional().describe(\"New text content for the cell\"),\n bold: z.boolean().optional(),\n italic: z.boolean().optional(),\n fontSize: z.number().optional(),\n alignment: z.enum([\"START\", \"CENTER\", \"END\", \"JUSTIFIED\"]).optional()\n});\n\nconst InsertImageFromUrlSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n imageUrl: z.string().url(\"Must be a valid URL\"),\n index: z.number().int().min(1, \"Index must be at least 1 (1-based)\"),\n width: z.number().optional().describe(\"Width in points\"),\n height: z.number().optional().describe(\"Height in points\")\n});\n\nconst InsertLocalImageSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n localImagePath: z.string().min(1, \"Local image path is required\"),\n index: z.number().int().min(1, \"Index must be at least 1 (1-based)\"),\n width: z.number().optional().describe(\"Width in points\"),\n height: z.number().optional().describe(\"Height in points\"),\n uploadToSameFolder: z.boolean().optional().default(true).describe(\"Upload to same folder as document\"),\n makePublic: z.boolean().optional().default(false).describe(\"Make uploaded image publicly accessible. Required if the document is not shared with the service account.\")\n});\n\nconst ListGoogleDocsSchema = z.object({\n maxResults: z.number().int().min(1).max(100).optional().default(20).describe(\"Maximum number of documents to return (1-100).\"),\n query: z.string().optional().describe(\"Search query to filter documents by name or content.\"),\n orderBy: z.enum([\"name\", \"modifiedTime\", \"createdTime\"]).optional().default(\"modifiedTime\").describe(\"Sort order for results.\")\n});\n\nconst GetDocumentInfoSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\")\n});\n\nconst FindAndReplaceInDocSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n findText: z.string().min(1, \"findText is required\"),\n replaceText: z.string(),\n matchCase: z.boolean().optional().default(false),\n dryRun: z.boolean().optional().default(false),\n tabId: z.string().optional(),\n});\n\nconst AddDocumentTabSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n title: z.string().min(1, \"Tab title is required\"),\n});\n\nconst RenameDocumentTabSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n tabId: z.string().min(1, \"Tab ID is required\"),\n title: z.string().min(1, \"Tab title is required\"),\n});\n\nconst InsertSmartChipSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n index: z.number().int().min(1, \"Index must be at least 1\"),\n chipType: z.enum([\"person\"]),\n personEmail: z.string().email(\"Valid email is required for person chip\"),\n});\n\nconst ReadSmartChipsSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n});\n\nconst CreateFootnoteSchema = z.object({\n documentId: z.string().min(1, \"Document ID is required\"),\n index: z.number().int().min(1, \"Index must be at least 1\").optional(),\n endOfSegment: z.boolean().optional(),\n content: z.string().optional(),\n}).refine(data => data.index !== undefined || data.endOfSegment === true, {\n message: \"Either 'index' or 'endOfSegment: true' must be provided\",\n});\n\n// ---------------------------------------------------------------------------\n// Tool definitions\n// ---------------------------------------------------------------------------\n\nexport const toolDefinitions: ToolDefinition[] = [\n {\n name: \"createGoogleDoc\",\n description: \"Create a new Google Doc\",\n inputSchema: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"Doc name\" },\n content: { type: \"string\", description: \"Doc content\" },\n parentFolderId: { type: \"string\", description: \"Parent folder ID\" }\n },\n required: [\"name\", \"content\"]\n }\n },\n {\n name: \"updateGoogleDoc\",\n description: \"Update an existing Google Doc (replaces all content). For multi-tab docs, specify tabId to replace a single tab's content atomically; leaves other tabs untouched.\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"Doc ID\" },\n content: { type: \"string\", description: \"New content\" },\n tabId: { type: \"string\", description: \"Optional. Tab ID to replace (from listDocumentTabs). If set, delete+insert run in a single atomic batchUpdate scoped to that tab.\" }\n },\n required: [\"documentId\", \"content\"]\n }\n },\n {\n name: \"insertText\",\n description: \"Insert text at a specific index in a Google Doc (surgical edit, doesn't replace entire doc). For multi-tab docs, specify tabId to target a specific tab.\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"The document ID\" },\n text: { type: \"string\", description: \"Text to insert\" },\n index: { type: \"number\", description: \"Position to insert at (1-based)\" },\n tabId: { type: \"string\", description: \"Optional. Tab ID to insert into (from listDocumentTabs). If omitted, inserts into the first/default tab.\" }\n },\n required: [\"documentId\", \"text\", \"index\"]\n }\n },\n {\n name: \"deleteRange\",\n description: \"Delete content between start and end indices in a Google Doc. For multi-tab docs, specify tabId to target a specific tab.\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"The document ID\" },\n startIndex: { type: \"number\", description: \"Start index (1-based, inclusive)\" },\n endIndex: { type: \"number\", description: \"End index (exclusive)\" },\n tabId: { type: \"string\", description: \"Optional. Tab ID to delete from (from listDocumentTabs). If omitted, deletes from the first/default tab.\" }\n },\n required: [\"documentId\", \"startIndex\", \"endIndex\"]\n }\n },\n {\n name: \"readGoogleDoc\",\n description: \"Read content of a Google Doc with format options. Supports multi-tab documents.\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"The document ID\" },\n format: { type: \"string\", enum: [\"text\", \"json\", \"markdown\"], description: \"Output format (default: text)\" },\n maxLength: { type: \"number\", description: \"Maximum characters to return\" },\n tabId: { type: \"string\", description: \"Read a specific tab by ID (from listDocumentTabs). If omitted, all tabs are returned.\" }\n },\n required: [\"documentId\"]\n }\n },\n {\n name: \"listDocumentTabs\",\n description: \"List all tabs in a Google Doc with their IDs and hierarchy\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"The document ID\" },\n includeContent: { type: \"boolean\", description: \"Include content summary (character count) for each tab\" }\n },\n required: [\"documentId\"]\n }\n },\n {\n name: \"applyTextStyle\",\n description: \"Apply text formatting (bold, italic, color, etc.) to a range or found text. Use EITHER startIndex+endIndex OR textToFind for targeting.\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"The document ID\" },\n startIndex: { type: \"number\", description: \"Start index (1-based) - use with endIndex\" },\n endIndex: { type: \"number\", description: \"End index (exclusive) - use with startIndex\" },\n textToFind: { type: \"string\", description: \"Text to find and format (alternative to indices)\" },\n matchInstance: { type: \"number\", description: \"Which instance of textToFind (default: 1)\" },\n bold: { type: \"boolean\", description: \"Make text bold\" },\n italic: { type: \"boolean\", description: \"Make text italic\" },\n underline: { type: \"boolean\", description: \"Underline text\" },\n strikethrough: { type: \"boolean\", description: \"Strikethrough text\" },\n fontSize: { type: \"number\", description: \"Font size in points\" },\n fontFamily: { type: \"string\", description: \"Font family name\" },\n foregroundColor: { type: \"string\", description: \"Hex color (e.g., #FF0000)\" },\n backgroundColor: { type: \"string\", description: \"Hex background color\" },\n linkUrl: { type: \"string\", description: \"URL for hyperlink\" }\n },\n required: [\"documentId\"]\n }\n },\n {\n name: \"applyParagraphStyle\",\n description: \"Apply paragraph formatting. Use EITHER startIndex+endIndex OR textToFind OR indexWithinParagraph for targeting.\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"The document ID\" },\n startIndex: { type: \"number\", description: \"Start index (1-based) - use with endIndex\" },\n endIndex: { type: \"number\", description: \"End index (exclusive) - use with startIndex\" },\n textToFind: { type: \"string\", description: \"Text within the target paragraph\" },\n matchInstance: { type: \"number\", description: \"Which instance of textToFind (default: 1)\" },\n indexWithinParagraph: { type: \"number\", description: \"Any index within the target paragraph\" },\n alignment: { type: \"string\", enum: [\"START\", \"END\", \"CENTER\", \"JUSTIFIED\"], description: \"Text alignment\" },\n indentStart: { type: \"number\", description: \"Left indent in points\" },\n indentEnd: { type: \"number\", description: \"Right indent in points\" },\n spaceAbove: { type: \"number\", description: \"Space above in points\" },\n spaceBelow: { type: \"number\", description: \"Space below in points\" },\n namedStyleType: { type: \"string\", enum: [\"NORMAL_TEXT\", \"TITLE\", \"SUBTITLE\", \"HEADING_1\", \"HEADING_2\", \"HEADING_3\", \"HEADING_4\", \"HEADING_5\", \"HEADING_6\"], description: \"Named paragraph style\" },\n keepWithNext: { type: \"boolean\", description: \"Keep with next paragraph\" }\n },\n required: [\"documentId\"]\n }\n },\n {\n name: \"formatGoogleDocText\",\n description: \"Apply text formatting (bold, italic, font, color, links) to a range or found text in a Google Doc. Alias for applyTextStyle.\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"The document ID\" },\n startIndex: { type: \"number\", description: \"Start index (1-based) - use with endIndex\" },\n endIndex: { type: \"number\", description: \"End index (exclusive) - use with startIndex\" },\n textToFind: { type: \"string\", description: \"Text to find and format (alternative to indices)\" },\n matchInstance: { type: \"number\", description: \"Which instance of textToFind (default: 1)\" },\n bold: { type: \"boolean\", description: \"Make text bold\" },\n italic: { type: \"boolean\", description: \"Make text italic\" },\n underline: { type: \"boolean\", description: \"Underline text\" },\n strikethrough: { type: \"boolean\", description: \"Strikethrough text\" },\n fontSize: { type: \"number\", description: \"Font size in points\" },\n fontFamily: { type: \"string\", description: \"Font family name\" },\n foregroundColor: { type: \"string\", description: \"Hex color (e.g., #FF0000)\" },\n backgroundColor: { type: \"string\", description: \"Hex background color\" },\n linkUrl: { type: \"string\", description: \"URL for hyperlink\" }\n },\n required: [\"documentId\"]\n }\n },\n {\n name: \"formatGoogleDocParagraph\",\n description: \"Apply paragraph formatting (alignment, indentation, spacing, heading style) in a Google Doc. Alias for applyParagraphStyle.\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"The document ID\" },\n startIndex: { type: \"number\", description: \"Start index (1-based) - use with endIndex\" },\n endIndex: { type: \"number\", description: \"End index (exclusive) - use with startIndex\" },\n textToFind: { type: \"string\", description: \"Text within the target paragraph\" },\n matchInstance: { type: \"number\", description: \"Which instance of textToFind (default: 1)\" },\n indexWithinParagraph: { type: \"number\", description: \"Any index within the target paragraph\" },\n alignment: { type: \"string\", enum: [\"START\", \"END\", \"CENTER\", \"JUSTIFIED\"], description: \"Text alignment\" },\n indentStart: { type: \"number\", description: \"Left indent in points\" },\n indentEnd: { type: \"number\", description: \"Right indent in points\" },\n spaceAbove: { type: \"number\", description: \"Space above in points\" },\n spaceBelow: { type: \"number\", description: \"Space below in points\" },\n namedStyleType: { type: \"string\", enum: [\"NORMAL_TEXT\", \"TITLE\", \"SUBTITLE\", \"HEADING_1\", \"HEADING_2\", \"HEADING_3\", \"HEADING_4\", \"HEADING_5\", \"HEADING_6\"], description: \"Named paragraph style\" },\n keepWithNext: { type: \"boolean\", description: \"Keep with next paragraph\" }\n },\n required: [\"documentId\"]\n }\n },\n {\n name: \"createParagraphBullets\",\n description: \"Add or remove bullet points / numbered lists on paragraphs in a Google Doc. Target paragraphs by startIndex+endIndex or textToFind. Use bulletPreset='NONE' to remove bullets.\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"The document ID\" },\n startIndex: { type: \"number\", description: \"Start index (1-based) - use with endIndex\" },\n endIndex: { type: \"number\", description: \"End index (exclusive) - use with startIndex\" },\n textToFind: { type: \"string\", description: \"Text within the target paragraph(s) to bulletize\" },\n matchInstance: { type: \"number\", description: \"Which instance of textToFind (default: 1)\" },\n bulletPreset: { type: \"string\", enum: [\"BULLET_DISC_CIRCLE_SQUARE\", \"BULLET_DIAMONDX_ARROW3D_SQUARE\", \"BULLET_CHECKBOX\", \"BULLET_ARROW_DIAMOND_DISC\", \"BULLET_STAR_CIRCLE_SQUARE\", \"BULLET_ARROW3D_CIRCLE_SQUARE\", \"BULLET_LEFTTRIANGLE_DIAMOND_DISC\", \"NUMBERED_DECIMAL_ALPHA_ROMAN\", \"NUMBERED_DECIMAL_ALPHA_ROMAN_PARENS\", \"NUMBERED_DECIMAL_NESTED\", \"NUMBERED_UPPERALPHA_ALPHA_ROMAN\", \"NUMBERED_UPPERROMAN_UPPERALPHA_DECIMAL\", \"NUMBERED_ZERODECIMAL_ALPHA_ROMAN\", \"NONE\"], description: \"Bullet style preset. Use NONE to remove bullets. Default: BULLET_DISC_CIRCLE_SQUARE\" }\n },\n required: [\"documentId\"]\n }\n },\n {\n name: \"findAndReplaceInDoc\",\n description: \"Find and replace text across a Google Document. Dry-run mode counts matches from paragraph text only (may differ from actual replacements which cover tables, headers, footers, etc.). For multi-tab docs, specify tabId to scope replacements to a single tab.\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"The document ID\" },\n findText: { type: \"string\", description: \"Text to find\" },\n replaceText: { type: \"string\", description: \"Replacement text\" },\n matchCase: { type: \"boolean\", description: \"Case-sensitive match (default: false)\" },\n dryRun: { type: \"boolean\", description: \"Only count approximate matches from paragraph text, do not modify document (default: false). Ignores tabId \u2014 always scans the full document body.\" },\n tabId: { type: \"string\", description: \"Optional. Tab ID to scope replacements to (from listDocumentTabs). If omitted, replaces across all tabs.\" }\n },\n required: [\"documentId\", \"findText\", \"replaceText\"]\n }\n },\n {\n name: \"listComments\",\n description: \"List all comments in a Google Document\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"The document ID\" },\n includeDeleted: { type: \"boolean\", description: \"Whether to include deleted comments (default: false)\" },\n pageSize: { type: \"number\", description: \"Max comments to return (1-100, default: 100)\" },\n pageToken: { type: \"string\", description: \"Token for next page of results\" },\n },\n required: [\"documentId\"]\n }\n },\n {\n name: \"getComment\",\n description: \"Get a specific comment with its full thread of replies\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"The document ID\" },\n commentId: { type: \"string\", description: \"The comment ID\" }\n },\n required: [\"documentId\", \"commentId\"]\n }\n },\n {\n name: \"addComment\",\n description: \"Add a comment anchored to a specific text range. Note: Due to Google API limitations, programmatic comments appear in 'All Comments' but may not be visibly anchored in the document UI.\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"The document ID\" },\n startIndex: { type: \"number\", description: \"Start index (1-based)\" },\n endIndex: { type: \"number\", description: \"End index (exclusive)\" },\n commentText: { type: \"string\", description: \"The comment content\" }\n },\n required: [\"documentId\", \"startIndex\", \"endIndex\", \"commentText\"]\n }\n },\n {\n name: \"replyToComment\",\n description: \"Add a reply to an existing comment\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"The document ID\" },\n commentId: { type: \"string\", description: \"The comment ID to reply to\" },\n replyText: { type: \"string\", description: \"The reply content\" },\n resolve: { type: \"boolean\", description: \"Set to true to resolve the comment thread after replying (default: false)\" }\n },\n required: [\"documentId\", \"commentId\", \"replyText\"]\n }\n },\n {\n name: \"deleteComment\",\n description: \"Delete a comment from the document\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"The document ID\" },\n commentId: { type: \"string\", description: \"The comment ID to delete\" }\n },\n required: [\"documentId\", \"commentId\"]\n }\n },\n {\n name: \"getGoogleDocContent\",\n description: \"Get content of a Google Doc with text indices for formatting\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"Document ID\" },\n includeFormatting: { type: \"boolean\", description: \"Include font, style, and color info for each text span (default: false)\" },\n },\n required: [\"documentId\"]\n }\n },\n {\n name: \"insertTable\",\n description: \"Insert a new table with the specified dimensions at a given index\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"The document ID\" },\n rows: { type: \"number\", description: \"Number of rows for the new table\" },\n columns: { type: \"number\", description: \"Number of columns for the new table\" },\n index: { type: \"number\", description: \"The index (1-based) where the table should be inserted\" }\n },\n required: [\"documentId\", \"rows\", \"columns\", \"index\"]\n }\n },\n {\n name: \"editTableCell\",\n description: \"Edit the content and/or style of a specific table cell. Requires knowing the table start index.\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"The document ID\" },\n tableStartIndex: { type: \"number\", description: \"The starting index of the TABLE element\" },\n rowIndex: { type: \"number\", description: \"Row index (0-based)\" },\n columnIndex: { type: \"number\", description: \"Column index (0-based)\" },\n textContent: { type: \"string\", description: \"New text content for the cell (replaces existing)\" },\n bold: { type: \"boolean\", description: \"Make text bold\" },\n italic: { type: \"boolean\", description: \"Make text italic\" },\n fontSize: { type: \"number\", description: \"Font size in points\" },\n alignment: { type: \"string\", enum: [\"START\", \"CENTER\", \"END\", \"JUSTIFIED\"], description: \"Text alignment\" }\n },\n required: [\"documentId\", \"tableStartIndex\", \"rowIndex\", \"columnIndex\"]\n }\n },\n {\n name: \"insertImageFromUrl\",\n description: \"Insert an inline image into a Google Document from a publicly accessible URL\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"The document ID\" },\n imageUrl: { type: \"string\", description: \"Publicly accessible URL to the image\" },\n index: { type: \"number\", description: \"The index (1-based) where the image should be inserted\" },\n width: { type: \"number\", description: \"Width of the image in points\" },\n height: { type: \"number\", description: \"Height of the image in points\" }\n },\n required: [\"documentId\", \"imageUrl\", \"index\"]\n }\n },\n {\n name: \"insertLocalImage\",\n description: \"Upload a local image file to Google Drive and insert it into a Google Document\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"The document ID\" },\n localImagePath: { type: \"string\", description: \"Absolute path to the local image file\" },\n index: { type: \"number\", description: \"The index (1-based) where the image should be inserted\" },\n width: { type: \"number\", description: \"Width of the image in points\" },\n height: { type: \"number\", description: \"Height of the image in points\" },\n uploadToSameFolder: { type: \"boolean\", description: \"Upload to same folder as document (default: true)\" },\n makePublic: { type: \"boolean\", description: \"Make uploaded image publicly accessible (anyone with the link can view). Set to true if the Docs API cannot access the image through the authenticated user's permissions. Default: false\" }\n },\n required: [\"documentId\", \"localImagePath\", \"index\"]\n }\n },\n {\n name: \"listGoogleDocs\",\n description: \"Lists Google Documents from your Google Drive with optional filtering.\",\n inputSchema: {\n type: \"object\",\n properties: {\n maxResults: { type: \"integer\", description: \"Maximum number of documents to return (1-100).\" },\n query: { type: \"string\", description: \"Search query to filter documents by name or content.\" },\n orderBy: { type: \"string\", enum: [\"name\", \"modifiedTime\", \"createdTime\"], description: \"Sort order for results.\" }\n },\n required: []\n }\n },\n {\n name: \"getDocumentInfo\",\n description: \"Gets detailed information about a specific Google Document.\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"The ID of the Google Document (from the URL).\" }\n },\n required: [\"documentId\"]\n }\n },\n {\n name: \"addDocumentTab\",\n description: \"Add a new tab in a Google Doc\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"Document ID\" },\n title: { type: \"string\", description: \"Tab title\" }\n },\n required: [\"documentId\", \"title\"]\n }\n },\n {\n name: \"renameDocumentTab\",\n description: \"Rename an existing Google Doc tab\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"Document ID\" },\n tabId: { type: \"string\", description: \"Tab ID\" },\n title: { type: \"string\", description: \"New tab title\" }\n },\n required: [\"documentId\", \"tabId\", \"title\"]\n }\n },\n {\n name: \"insertSmartChip\",\n description: \"Insert a person smart chip (mention) at a document index. Only person chips are supported by the Docs API; date and file chips are read-only.\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"Document ID\" },\n index: { type: \"number\", description: \"Insertion index (1-based)\" },\n chipType: { type: \"string\", enum: [\"person\"], description: \"Smart chip type (only 'person' is supported)\" },\n personEmail: { type: \"string\", description: \"Email address for the person mention\" }\n },\n required: [\"documentId\", \"index\", \"chipType\", \"personEmail\"]\n }\n },\n {\n name: \"readSmartChips\",\n description: \"Read smart chip-like elements (person mentions, rich links, date chips) from the default tab of a document\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"Document ID\" }\n },\n required: [\"documentId\"]\n }\n },\n {\n name: \"createFootnote\",\n description: \"Create a footnote in a Google Doc. Footnotes cannot be inserted inside equations, headers, footers, or other footnotes.\",\n inputSchema: {\n type: \"object\",\n properties: {\n documentId: { type: \"string\", description: \"Document ID\" },\n index: { type: \"number\", description: \"1-based character index where the footnote reference should be inserted\" },\n endOfSegment: { type: \"boolean\", description: \"If true, insert footnote at the end of the document body (use instead of index)\" },\n content: { type: \"string\", description: \"Optional text content for the footnote body\" },\n },\n required: [\"documentId\"]\n }\n },\n];\n\n// ---------------------------------------------------------------------------\n// Handler\n// ---------------------------------------------------------------------------\n\nexport async function handleTool(toolName: string, args: Record<string, unknown>, ctx: ToolContext): Promise<ToolResult | null> {\n switch (toolName) {\n\n // =========================================================================\n // CREATE / UPDATE GOOGLE DOC\n // =========================================================================\n\n case \"createGoogleDoc\": {\n const validation = CreateGoogleDocSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const parentFolderId = await ctx.resolveFolderId(a.parentFolderId);\n\n // Check if document already exists\n const existingFileId = await ctx.checkFileExists(a.name, parentFolderId);\n if (existingFileId) {\n return errorResponse(\n `A document named \"${a.name}\" already exists in this location. ` +\n `To update it, use updateGoogleDoc with documentId: ${existingFileId}`\n );\n }\n\n // Create empty doc\n let docResponse;\n try {\n docResponse = await ctx.getDrive().files.create({\n requestBody: {\n name: a.name,\n mimeType: 'application/vnd.google-apps.document',\n parents: [parentFolderId]\n },\n fields: 'id, name, webViewLink',\n supportsAllDrives: true\n });\n } catch (createError: any) {\n ctx.log('Drive files.create error details:', {\n message: createError.message,\n code: createError.code,\n errors: createError.errors,\n status: createError.status\n });\n throw createError;\n }\n const doc = docResponse.data;\n\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n await docs.documents.batchUpdate({\n documentId: doc.id!,\n requestBody: {\n requests: [\n {\n insertText: { location: { index: 1 }, text: a.content }\n },\n // Ensure the text is formatted as normal text, not as a header\n {\n updateParagraphStyle: {\n range: {\n startIndex: 1,\n endIndex: a.content.length + 1\n },\n paragraphStyle: {\n namedStyleType: 'NORMAL_TEXT'\n },\n fields: 'namedStyleType'\n }\n }\n ]\n }\n });\n\n return {\n content: [{ type: \"text\", text: `Created Google Doc: ${doc.name}\\nID: ${doc.id}\\nLink: ${doc.webViewLink}` }],\n isError: false\n };\n }\n\n case \"updateGoogleDoc\": {\n const validation = UpdateGoogleDocSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n\n if (a.tabId) {\n // Tab-scoped path: single atomic batchUpdate so a failed insert can't leave the tab wiped.\n const document = await docs.documents.get({ documentId: a.documentId, includeTabsContent: true });\n const tabs = (document.data as any).tabs as any[] | undefined;\n const tab = tabs ? findTabById(tabs, a.tabId) : null;\n if (!tab) {\n return errorResponse(`Tab with ID \"${a.tabId}\" not found. Use listDocumentTabs to see available tabs.`);\n }\n\n const bodyContent = tab.documentTab?.body?.content;\n const lastEndIndex = bodyContent?.[bodyContent.length - 1]?.endIndex ?? 1;\n const deleteEndIndex = Math.max(1, lastEndIndex - 1);\n\n const requests: any[] = [];\n if (deleteEndIndex > 1) {\n requests.push({\n deleteContentRange: {\n range: { startIndex: 1, endIndex: deleteEndIndex, tabId: a.tabId }\n }\n });\n }\n requests.push({\n insertText: { location: { index: 1, tabId: a.tabId }, text: a.content }\n });\n requests.push({\n updateParagraphStyle: {\n range: { startIndex: 1, endIndex: a.content.length + 1, tabId: a.tabId },\n paragraphStyle: { namedStyleType: 'NORMAL_TEXT' },\n fields: 'namedStyleType'\n }\n });\n\n await docs.documents.batchUpdate({\n documentId: a.documentId,\n requestBody: { requests }\n });\n\n return {\n content: [{ type: \"text\", text: `Updated Google Doc: ${document.data.title} (tab: ${a.tabId})` }],\n isError: false\n };\n }\n\n const document = await docs.documents.get({ documentId: a.documentId });\n\n // Delete all content\n const endIndex = document.data.body?.content?.[document.data.body.content.length - 1]?.endIndex || 1;\n const deleteEndIndex = Math.max(1, endIndex - 1);\n\n if (deleteEndIndex > 1) {\n await docs.documents.batchUpdate({\n documentId: a.documentId,\n requestBody: {\n requests: [{\n deleteContentRange: {\n range: { startIndex: 1, endIndex: deleteEndIndex }\n }\n }]\n }\n });\n }\n\n // Insert new content\n await docs.documents.batchUpdate({\n documentId: a.documentId,\n requestBody: {\n requests: [\n {\n insertText: { location: { index: 1 }, text: a.content }\n },\n {\n updateParagraphStyle: {\n range: {\n startIndex: 1,\n endIndex: a.content.length + 1\n },\n paragraphStyle: {\n namedStyleType: 'NORMAL_TEXT'\n },\n fields: 'namedStyleType'\n }\n }\n ]\n }\n });\n\n return {\n content: [{ type: \"text\", text: `Updated Google Doc: ${document.data.title}` }],\n isError: false\n };\n }\n\n // =========================================================================\n // DOC CONTENT\n // =========================================================================\n\n case \"getGoogleDocContent\": {\n const validation = GetGoogleDocContentSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n const withFormatting = a.includeFormatting === true;\n\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n const document = await docs.documents.get({\n documentId: a.documentId,\n includeTabsContent: true,\n });\n\n interface Segment {\n text: string;\n startIndex: number;\n endIndex: number;\n fontFamily?: string;\n fontSize?: number;\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n strikethrough?: boolean;\n foregroundColor?: string;\n backgroundColor?: string;\n }\n\n // Helper to resolve inline element text for non-textRun elements\n function resolveInlineElementText(el: any, inlineObjects?: any): string | null {\n if (el.person?.personProperties) {\n const p = el.person.personProperties;\n if (p.name && p.email) return `@${p.name} (${p.email})`;\n return `@${p.name || p.email || ''}`;\n }\n if (el.richLink?.richLinkProperties) {\n const rl = el.richLink.richLinkProperties;\n const title = (rl.title || rl.uri || '').replace(/[\\[\\]]/g, '\\\\$&');\n const uri = rl.uri;\n return title && uri ? `[${title}](${uri})` : title || null;\n }\n if (el.inlineObjectElement?.inlineObjectId) {\n if (inlineObjects) {\n const obj = inlineObjects[el.inlineObjectElement.inlineObjectId];\n const desc = obj?.inlineObjectProperties?.embeddedObject?.description\n || obj?.inlineObjectProperties?.embeddedObject?.title;\n return desc ? `[image: ${desc}]` : '[image]';\n }\n return '[image]';\n }\n if (el.footnoteReference) {\n return `[^${el.footnoteReference.footnoteNumber || ''}]`;\n }\n if (el.horizontalRule) {\n return '---\\n';\n }\n return null;\n }\n\n // Helper to extract segments from body content\n // Table cell extraction reuses processContent so that any element handling\n // (inline elements, formatting, etc.) automatically applies inside table\n // cells as well.\n function extractSegments(bodyContent: any[], inlineObjects?: any): Segment[] {\n const segments: Segment[] = [];\n\n // Extract plain text from a table cell by running its content through\n // processContent and collecting the text from the produced segments.\n function getCellText(cellContent: any[]): string {\n const before = segments.length;\n processContent(cellContent);\n const cellSegs = segments.splice(before);\n // Strip trailing newlines, join paragraphs with space, then escape\n // pipe characters so they don't create extra markdown columns.\n return cellSegs\n .map(s => s.text.replace(/\\n$/g, ''))\n .join(' ')\n .replace(/\\|/g, '\\\\|')\n .trim();\n }\n\n function processContent(content: any[]) {\n for (const element of content) {\n if (element.paragraph?.elements) {\n for (const textElement of element.paragraph.elements) {\n if (textElement.textRun?.content && textElement.startIndex != null && textElement.endIndex != null) {\n const seg: Segment = {\n text: textElement.textRun.content,\n startIndex: textElement.startIndex,\n endIndex: textElement.endIndex,\n };\n if (withFormatting) {\n const ts = textElement.textRun.textStyle;\n if (ts) {\n if (ts.weightedFontFamily?.fontFamily) seg.fontFamily = ts.weightedFontFamily.fontFamily;\n if (ts.fontSize?.magnitude != null) seg.fontSize = ts.fontSize.magnitude;\n if (ts.bold) seg.bold = true;\n if (ts.italic) seg.italic = true;\n if (ts.underline) seg.underline = true;\n if (ts.strikethrough) seg.strikethrough = true;\n const fg = rgbColorToHex(ts.foregroundColor);\n const bg = rgbColorToHex(ts.backgroundColor);\n if (fg) seg.foregroundColor = fg;\n if (bg) seg.backgroundColor = bg;\n }\n }\n segments.push(seg);\n } else {\n // Handle non-textRun inline elements (person chips, rich links, images, footnotes, horizontal rules)\n const inlineText = resolveInlineElementText(textElement, inlineObjects);\n if (inlineText && textElement.startIndex != null && textElement.endIndex != null) {\n segments.push({\n text: inlineText,\n startIndex: textElement.startIndex,\n endIndex: textElement.endIndex,\n });\n }\n }\n }\n } else if (element.table?.tableRows) {\n const rows: string[] = [];\n for (let rowIdx = 0; rowIdx < element.table.tableRows.length; rowIdx++) {\n const row = element.table.tableRows[rowIdx];\n if (!row.tableCells) continue;\n const cellTexts: string[] = [];\n for (const cell of row.tableCells) {\n cellTexts.push(cell.content ? getCellText(cell.content) : '');\n }\n rows.push('| ' + cellTexts.join(' | ') + ' |');\n if (rowIdx === 0) {\n rows.push('| ' + cellTexts.map(() => '---').join(' | ') + ' |');\n }\n }\n const md = rows.join('\\n') + '\\n\\n';\n if (element.startIndex != null && element.endIndex != null) {\n segments.push({\n text: md,\n startIndex: element.startIndex,\n endIndex: element.endIndex,\n });\n }\n } else if (element.tableOfContents?.content) {\n processContent(element.tableOfContents.content);\n }\n }\n }\n\n processContent(bodyContent);\n return segments;\n }\n\n // Helper to format segments into indexed text\n function formatSegments(segments: Segment[]): string {\n let result = '';\n for (const segment of segments) {\n const hasMeta = withFormatting && hasFormattingInfo(segment);\n const meta = hasMeta ? buildMetaLine(segment) : null;\n const lines = segment.text.split('\\n');\n let offset = segment.startIndex;\n for (const line of lines) {\n if (line.trim()) {\n if (meta) {\n result += `[${offset}-${offset + line.length}] ${meta}\\n ${line}\\n`;\n } else {\n result += `[${offset}-${offset + line.length}] ${line}\\n`;\n }\n }\n offset += line.length + 1;\n }\n }\n return result;\n }\n\n function hasFormattingInfo(seg: Segment): boolean {\n return !!(seg.fontFamily || seg.fontSize || seg.bold || seg.italic || seg.underline || seg.strikethrough || seg.foregroundColor || seg.backgroundColor);\n }\n\n function buildMetaLine(seg: Segment): string {\n const parts: string[] = [];\n if (seg.fontFamily) parts.push(`font=\"${seg.fontFamily}\"`);\n if (seg.fontSize) parts.push(`size=${seg.fontSize}pt`);\n const styles: string[] = [];\n if (seg.bold) styles.push('bold');\n if (seg.italic) styles.push('italic');\n if (seg.underline) styles.push('underline');\n if (seg.strikethrough) styles.push('strikethrough');\n if (styles.length > 0) parts.push(`style=${styles.join(',')}`);\n if (seg.foregroundColor) parts.push(`color=${seg.foregroundColor}`);\n if (seg.backgroundColor) parts.push(`bg=${seg.backgroundColor}`);\n return parts.join(', ');\n }\n\n // Accumulate font usage across all segments\n interface FontInfo { sizes: Set<number>; styles: Set<string>; charCount: number }\n const fontUsage: Map<string, FontInfo> = new Map();\n function trackFonts(segments: Segment[]) {\n if (!withFormatting) return;\n for (const seg of segments) {\n if (seg.fontFamily) {\n let info = fontUsage.get(seg.fontFamily);\n if (!info) {\n info = { sizes: new Set(), styles: new Set(), charCount: 0 };\n fontUsage.set(seg.fontFamily, info);\n }\n if (seg.fontSize) info.sizes.add(seg.fontSize);\n if (seg.bold) info.styles.add('bold');\n if (seg.italic) info.styles.add('italic');\n if (seg.underline) info.styles.add('underline');\n if (seg.strikethrough) info.styles.add('strikethrough');\n info.charCount += seg.endIndex - seg.startIndex;\n }\n }\n }\n\n const tabs = (document.data as any).tabs as any[] | undefined;\n let formattedContent = 'Document content with indices:\\n\\n';\n let totalLength = 0;\n\n if (tabs && tabs.length > 0) {\n const allTabs = collectAllTabsWithLevel(tabs);\n const isMultiTab = allTabs.length > 1;\n for (const { tab, level } of allTabs) {\n const bodyContent = tab.documentTab?.body?.content;\n // Multi-tab: include all tabs with headers\n if (isMultiTab) {\n const title = tab.tabProperties?.title || 'Untitled';\n const indent = ' '.repeat(level);\n formattedContent += `${indent}=== Tab: ${title} ===\\n`;\n }\n if (bodyContent) {\n const tabInlineObjects = tab.documentTab?.inlineObjects;\n const segments = extractSegments(bodyContent, tabInlineObjects);\n trackFonts(segments);\n formattedContent += formatSegments(segments);\n if (segments.length > 0) {\n totalLength += segments[segments.length - 1].endIndex;\n }\n }\n // Multi-tab: add new line between tabs\n if (isMultiTab) {\n formattedContent += '\\n';\n }\n }\n } else {\n // Fallback to legacy body content\n const bodyContent = document.data.body?.content;\n if (bodyContent) {\n const legacyInlineObjects = (document.data as any).inlineObjects;\n const segments = extractSegments(bodyContent, legacyInlineObjects);\n trackFonts(segments);\n formattedContent += formatSegments(segments);\n totalLength = segments.length > 0 ? segments[segments.length - 1].endIndex : 0;\n }\n }\n\n if (withFormatting && fontUsage.size > 0) {\n formattedContent += '\\n--- Fonts summary ---\\n';\n const sorted = [...fontUsage.entries()].sort((a, b) => b[1].charCount - a[1].charCount);\n for (const [font, info] of sorted) {\n const sizesStr = info.sizes.size > 0 ? [...info.sizes].sort((a, b) => a - b).join(', ') + ' pt' : 'default size';\n const stylesStr = info.styles.size > 0 ? [...info.styles].sort().join(', ') : 'normal';\n formattedContent += `${font}: sizes [${sizesStr}], styles [${stylesStr}], ~${info.charCount} chars\\n`;\n }\n }\n\n return {\n content: [{\n type: \"text\",\n text: formattedContent + `\\nTotal length: ${totalLength} characters`\n }],\n isError: false\n };\n }\n\n // =========================================================================\n // DOC EDITING TOOLS\n // =========================================================================\n\n case \"insertText\": {\n const validation = InsertTextSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const location: { index: number; tabId?: string } = { index: a.index };\n if (a.tabId) location.tabId = a.tabId;\n\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n await docs.documents.batchUpdate({\n documentId: a.documentId,\n requestBody: {\n requests: [{\n insertText: {\n location,\n text: a.text\n }\n }]\n }\n });\n\n return {\n content: [{ type: \"text\", text: `Successfully inserted ${a.text.length} characters at index ${a.index}${a.tabId ? ` in tab ${a.tabId}` : ''}` }],\n isError: false\n };\n }\n\n case \"deleteRange\": {\n const validation = DeleteRangeSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n if (a.endIndex <= a.startIndex) {\n return errorResponse(\"endIndex must be greater than startIndex\");\n }\n\n const range: { startIndex: number; endIndex: number; tabId?: string } = {\n startIndex: a.startIndex,\n endIndex: a.endIndex\n };\n if (a.tabId) range.tabId = a.tabId;\n\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n await docs.documents.batchUpdate({\n documentId: a.documentId,\n requestBody: {\n requests: [{\n deleteContentRange: { range }\n }]\n }\n });\n\n return {\n content: [{ type: \"text\", text: `Successfully deleted content from index ${a.startIndex} to ${a.endIndex}${a.tabId ? ` in tab ${a.tabId}` : ''}` }],\n isError: false\n };\n }\n\n case \"readGoogleDoc\": {\n const validation = ReadGoogleDocSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n const docResponse = await docs.documents.get({\n documentId: a.documentId,\n includeTabsContent: true,\n });\n\n const doc = docResponse.data;\n const format = a.format || 'text';\n\n if (format === 'json') {\n let result = JSON.stringify(doc, null, 2);\n if (a.maxLength && result.length > a.maxLength) {\n result = result.substring(0, a.maxLength) + '\\n... (truncated)';\n }\n return {\n content: [{ type: \"text\", text: result }],\n isError: false\n };\n }\n\n // Helper to extract plain text from body content\n function extractText(bodyContent: any[]): string {\n let result = '';\n for (const element of bodyContent) {\n if (element.paragraph?.elements) {\n for (const elem of element.paragraph.elements) {\n if (elem.textRun?.content) {\n result += elem.textRun.content;\n }\n }\n } else if (element.table) {\n for (const row of element.table.tableRows || []) {\n for (const cell of row.tableCells || []) {\n for (const cellContent of cell.content || []) {\n if (cellContent.paragraph?.elements) {\n for (const elem of cellContent.paragraph.elements) {\n if (elem.textRun?.content) {\n result += elem.textRun.content;\n }\n }\n }\n }\n result += '\\t';\n }\n result += '\\n';\n }\n }\n }\n return result;\n }\n\n let text = '';\n const tabs = (doc as any).tabs as any[] | undefined;\n\n if (tabs && tabs.length > 0) {\n if (a.tabId) {\n // Find the specific tab (recursively through childTabs)\n const tab = findTabById(tabs, a.tabId);\n if (!tab) {\n return errorResponse(`Tab with ID \"${a.tabId}\" not found. Use listDocumentTabs to see available tabs.`);\n }\n const bodyContent = tab.documentTab?.body?.content;\n if (bodyContent) {\n text = extractText(bodyContent);\n }\n } else {\n const allTabs = collectAllTabsWithLevel(tabs);\n const isMultiTab = allTabs.length > 1;\n for (const { tab, level } of allTabs) {\n const bodyContent = tab.documentTab?.body?.content;\n // Multi-tab: include all tabs with headers\n if (isMultiTab) {\n const title = tab.tabProperties?.title || 'Untitled';\n const indent = ' '.repeat(level);\n text += `${indent}=== Tab: ${title} ===\\n`;\n }\n if (bodyContent) {\n text += extractText(bodyContent);\n }\n // Multi-tab: add new line between tabs\n if (isMultiTab) {\n text += '\\n';\n }\n }\n }\n } else {\n // Fallback to legacy body content\n const body = doc.body;\n if (body?.content) {\n text = extractText(body.content);\n }\n }\n\n if (format === 'markdown') {\n text = `# ${doc.title}\\n\\n${text}`;\n }\n\n if (a.maxLength && text.length > a.maxLength) {\n text = text.substring(0, a.maxLength) + '\\n... (truncated)';\n }\n\n return {\n content: [{ type: \"text\", text }],\n isError: false\n };\n }\n\n case \"listDocumentTabs\": {\n const validation = ListDocumentTabsSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n // Use includeTabsContent to get the new tabs structure\n const docResponse = await docs.documents.get({\n documentId: a.documentId,\n includeTabsContent: true\n });\n\n const doc = docResponse.data;\n\n // Check if document has tabs (newer API feature)\n const tabs = (doc as any).tabs;\n if (!tabs || tabs.length === 0) {\n // Single-tab document or legacy format - check for body content\n let contentInfo = '';\n if (a.includeContent) {\n let charCount = 0;\n const body = doc.body;\n if (body?.content) {\n for (const element of body.content) {\n if (element.paragraph?.elements) {\n for (const elem of element.paragraph.elements) {\n if (elem.textRun?.content) {\n charCount += elem.textRun.content.length;\n }\n }\n }\n }\n }\n contentInfo = ` (${charCount} characters)`;\n }\n return {\n content: [{ type: \"text\", text: `Document \"${doc.title}\" has a single tab (standard format).${contentInfo}` }],\n isError: false\n };\n }\n\n // Process tabs\n const processTab = (tab: any, depth: number = 0): string => {\n const indent = ' '.repeat(depth);\n let result = `${indent}- Tab: \"${tab.tabProperties?.title || 'Untitled'}\" (ID: ${tab.tabProperties?.tabId})`;\n\n if (a.includeContent && tab.documentTab?.body?.content) {\n let charCount = 0;\n for (const element of tab.documentTab.body.content) {\n if (element.paragraph?.elements) {\n for (const elem of element.paragraph.elements) {\n if (elem.textRun?.content) {\n charCount += elem.textRun.content.length;\n }\n }\n }\n }\n result += ` (${charCount} characters)`;\n }\n\n if (tab.childTabs) {\n for (const childTab of tab.childTabs) {\n result += '\\n' + processTab(childTab, depth + 1);\n }\n }\n\n return result;\n };\n\n let tabList = `Document \"${doc.title}\" tabs:\\n`;\n for (const tab of tabs) {\n tabList += processTab(tab) + '\\n';\n }\n\n return {\n content: [{ type: \"text\", text: tabList }],\n isError: false\n };\n }\n\n // =========================================================================\n // TEXT & PARAGRAPH STYLE\n // =========================================================================\n\n case \"applyTextStyle\":\n case \"formatGoogleDocText\": {\n const validation = ApplyTextStyleSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n let startIndex: number;\n let endIndex: number;\n\n // Determine target range (flat parameters)\n if (a.startIndex !== undefined && a.endIndex !== undefined) {\n startIndex = a.startIndex;\n endIndex = a.endIndex;\n } else if (a.textToFind !== undefined) {\n const range = await findTextRange(\n ctx,\n a.documentId,\n a.textToFind,\n a.matchInstance || 1\n );\n if (!range) {\n return errorResponse(`Text \"${a.textToFind}\" not found in document`);\n }\n startIndex = range.startIndex;\n endIndex = range.endIndex;\n } else {\n return errorResponse(\"Must provide either startIndex+endIndex or textToFind\");\n }\n\n // Build style object from flat parameters\n const style = {\n bold: a.bold,\n italic: a.italic,\n underline: a.underline,\n strikethrough: a.strikethrough,\n fontSize: a.fontSize,\n fontFamily: a.fontFamily,\n foregroundColor: a.foregroundColor,\n backgroundColor: a.backgroundColor,\n linkUrl: a.linkUrl\n };\n\n // Build the update request\n const styleResult = buildUpdateTextStyleRequest(startIndex, endIndex, style);\n if (!styleResult) {\n return errorResponse(\"No valid style options provided\");\n }\n\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n await docs.documents.batchUpdate({\n documentId: a.documentId,\n requestBody: {\n requests: [styleResult.request]\n }\n });\n\n return {\n content: [{ type: \"text\", text: `Successfully applied text style to range ${startIndex}-${endIndex}` }],\n isError: false\n };\n }\n\n case \"applyParagraphStyle\":\n case \"formatGoogleDocParagraph\": {\n const validation = ApplyParagraphStyleSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n let startIndex: number;\n let endIndex: number;\n\n // Determine target range (flat parameters)\n if (a.startIndex !== undefined && a.endIndex !== undefined) {\n startIndex = a.startIndex;\n endIndex = a.endIndex;\n } else if (a.textToFind !== undefined) {\n const range = await findTextRange(\n ctx,\n a.documentId,\n a.textToFind,\n a.matchInstance || 1\n );\n if (!range) {\n return errorResponse(`Text \"${a.textToFind}\" not found in document`);\n }\n // For paragraph style, get the full paragraph range\n const paraRange = await getParagraphRange(ctx, a.documentId, range.startIndex);\n if (!paraRange) {\n return errorResponse(\"Could not determine paragraph boundaries\");\n }\n startIndex = paraRange.startIndex;\n endIndex = paraRange.endIndex;\n } else if (a.indexWithinParagraph !== undefined) {\n const paraRange = await getParagraphRange(ctx, a.documentId, a.indexWithinParagraph);\n if (!paraRange) {\n return errorResponse(\"Could not determine paragraph boundaries\");\n }\n startIndex = paraRange.startIndex;\n endIndex = paraRange.endIndex;\n } else {\n return errorResponse(\"Must provide either startIndex+endIndex, textToFind, or indexWithinParagraph\");\n }\n\n // Build style object from flat parameters\n const style = {\n alignment: a.alignment,\n indentStart: a.indentStart,\n indentEnd: a.indentEnd,\n spaceAbove: a.spaceAbove,\n spaceBelow: a.spaceBelow,\n namedStyleType: a.namedStyleType,\n keepWithNext: a.keepWithNext\n };\n\n // Build the update request\n const styleResult = buildUpdateParagraphStyleRequest(startIndex, endIndex, style);\n if (!styleResult) {\n return errorResponse(\"No valid style options provided\");\n }\n\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n await docs.documents.batchUpdate({\n documentId: a.documentId,\n requestBody: {\n requests: [styleResult.request]\n }\n });\n\n return {\n content: [{ type: \"text\", text: `Successfully applied paragraph style to range ${startIndex}-${endIndex}` }],\n isError: false\n };\n }\n\n\n case \"createParagraphBullets\": {\n const validation = CreateParagraphBulletsSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n let startIndex: number;\n let endIndex: number;\n\n if (a.startIndex !== undefined && a.endIndex !== undefined) {\n startIndex = a.startIndex;\n endIndex = a.endIndex;\n } else if (a.textToFind !== undefined) {\n const range = await findTextRange(\n ctx,\n a.documentId,\n a.textToFind,\n a.matchInstance || 1\n );\n if (!range) {\n return errorResponse(`Text \"${a.textToFind}\" not found in document`);\n }\n startIndex = range.startIndex;\n endIndex = range.endIndex;\n } else {\n return errorResponse(\"Must provide either startIndex+endIndex or textToFind\");\n }\n\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n\n if (a.bulletPreset === 'NONE') {\n await docs.documents.batchUpdate({\n documentId: a.documentId,\n requestBody: {\n requests: [{\n deleteParagraphBullets: {\n range: { startIndex, endIndex }\n }\n }]\n }\n });\n return {\n content: [{ type: \"text\", text: `Removed bullets from range ${startIndex}-${endIndex}` }],\n isError: false\n };\n }\n\n await docs.documents.batchUpdate({\n documentId: a.documentId,\n requestBody: {\n requests: [{\n createParagraphBullets: {\n range: { startIndex, endIndex },\n bulletPreset: a.bulletPreset\n }\n }]\n }\n });\n\n return {\n content: [{ type: \"text\", text: `Applied ${a.bulletPreset} bullets to range ${startIndex}-${endIndex}` }],\n isError: false\n };\n }\n\n case \"findAndReplaceInDoc\": {\n const validation = FindAndReplaceInDocSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n\n if (a.dryRun) {\n const doc = await docs.documents.get({ documentId: a.documentId });\n let text = '';\n const content = doc.data.body?.content || [];\n for (const el of content) {\n if (el.paragraph?.elements) {\n for (const elem of el.paragraph.elements) {\n if (elem.textRun?.content) text += elem.textRun.content;\n }\n }\n }\n const escaped = a.findText.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const flags = a.matchCase ? 'g' : 'gi';\n const matches = text.match(new RegExp(escaped, flags));\n const count = matches ? matches.length : 0;\n return {\n content: [{ type: 'text', text: `Dry run (paragraph text only, approximate): found ${count} occurrence(s) of \"${a.findText}\". Note: actual replacement covers the full document including tables, headers, and footers.` }],\n isError: false,\n };\n }\n\n const replaceAllText: {\n containsText: { text: string; matchCase: boolean };\n replaceText: string;\n tabsCriteria?: { tabIds: string[] };\n } = {\n containsText: { text: a.findText, matchCase: a.matchCase },\n replaceText: a.replaceText,\n };\n if (a.tabId) replaceAllText.tabsCriteria = { tabIds: [a.tabId] };\n\n const response = await docs.documents.batchUpdate({\n documentId: a.documentId,\n requestBody: {\n requests: [{ replaceAllText }],\n },\n });\n\n const occurrences = response.data.replies?.[0]?.replaceAllText?.occurrencesChanged ?? 0;\n return {\n content: [{ type: 'text', text: `Replaced ${occurrences} occurrence(s) of \"${a.findText}\"${a.tabId ? ` in tab ${a.tabId}` : ''}.` }],\n isError: false,\n };\n }\n\n // =========================================================================\n // COMMENT TOOLS (use Drive API v3)\n // =========================================================================\n\n case \"listComments\": {\n const validation = ListCommentsSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const response = await ctx.getDrive().comments.list({\n fileId: a.documentId,\n fields: 'comments(id,content,quotedFileContent,author,createdTime,resolved,replies(id,content,author,createdTime)),nextPageToken',\n pageSize: a.pageSize || 100,\n pageToken: a.pageToken,\n includeDeleted: a.includeDeleted || false,\n });\n\n const comments = response.data.comments || [];\n const nextPageToken = response.data.nextPageToken;\n\n if (comments.length === 0) {\n return {\n content: [{ type: \"text\", text: \"No comments found in this document.\" }],\n isError: false\n };\n }\n\n // \u2500\u2500 Comment context extraction (two-tiered) \u2500\u2500\n // Tier 1 (fast): Read doc via Docs API, find each comment's quotedFileContent\n // in the body text. If there's exactly one match, extract surrounding context.\n // Tier 2 (fallback): For ambiguous or failed Tier 1 comments, export as DOCX\n // and parse commentRangeStart/End XML markers. Match by (author, createdTime).\n const contextMap = new Map<string, CommentContext>();\n let flatText = '';\n let offsetMap: number[] = [];\n\n // \u2500\u2500 Tier 1: Docs API text matching \u2500\u2500\n // Check MIME type upfront \u2014 only Google Docs support the Docs API\n let needsDocxFallback = false;\n let isGoogleDoc = false;\n try {\n const fileInfo = await ctx.getDrive().files.get({\n fileId: a.documentId,\n fields: 'mimeType',\n supportsAllDrives: true,\n });\n isGoogleDoc = fileInfo.data.mimeType === 'application/vnd.google-apps.document';\n } catch (err) {\n ctx.log('Failed to check file MIME type:', err);\n }\n\n if (isGoogleDoc) {\n try {\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n const docResponse = await docs.documents.get({\n documentId: a.documentId,\n includeTabsContent: true,\n });\n\n const result = buildFlatTextFromDoc(docResponse.data);\n flatText = result.flatText;\n offsetMap = result.offsetMap;\n\n // Get surrounding context for a match at a flatText position\n function getContext(matchStart: number, matchLen: number): { before: string; after: string } {\n const matchText = flatText.substring(matchStart, matchStart + matchLen);\n const beforeStart = Math.max(0, matchStart - 120);\n let before = flatText.substring(beforeStart, matchStart).trim();\n if (beforeStart > 0) before = '...' + before;\n before = before + matchText;\n const afterEnd = Math.min(flatText.length, matchStart + matchLen + 120);\n let after = flatText.substring(matchStart + matchLen, afterEnd).trim();\n if (afterEnd < flatText.length) after = after + '...';\n after = matchText + after;\n return { before, after };\n }\n\n // For each comment, find all occurrences of its quotedFileContent in the doc\n const ambiguousComments: any[] = [];\n for (const comment of comments) {\n const quoted = comment.quotedFileContent?.value;\n if (!quoted) continue;\n\n const positions: number[] = [];\n let searchFrom = 0;\n while (true) {\n const idx = flatText.indexOf(quoted, searchFrom);\n if (idx === -1) break;\n positions.push(idx);\n searchFrom = idx + 1;\n }\n\n if (positions.length === 1) {\n const surrounding = getContext(positions[0], quoted.length);\n const entry: CommentContext = {\n contextBefore: surrounding.before,\n contextAfter: surrounding.after,\n };\n // Store Docs API character offsets with bounds check\n const endIdx = positions[0] + quoted.length - 1;\n if (endIdx < offsetMap.length) {\n entry.startIndex = offsetMap[positions[0]];\n entry.endIndex = offsetMap[endIdx] + 1;\n }\n if (comment.id) contextMap.set(comment.id, entry);\n } else if (positions.length > 1) {\n // Ambiguous \u2014 need DOCX fallback to disambiguate\n ambiguousComments.push(comment);\n }\n // positions.length === 0: quoted text not found (e.g., doc was edited since comment)\n }\n\n needsDocxFallback = ambiguousComments.length > 0;\n } catch (err) {\n ctx.log('Tier 1 context extraction failed:', err);\n needsDocxFallback = true;\n }\n }\n\n // \u2500\u2500 Tier 2: DOCX export fallback for ambiguous comments \u2500\u2500\n if (needsDocxFallback) {\n const unresolved = comments.filter((c: any) => !contextMap.has(c.id) && !c.resolved);\n\n if (unresolved.length > 0) {\n try {\n const docxResponse = await ctx.getDrive().files.export({\n fileId: a.documentId,\n mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n }, { responseType: 'arraybuffer' });\n\n const docxResult = await resolveContextFromDocx(docxResponse.data as ArrayBuffer);\n if (docxResult) {\n matchDocxToDriveComments(comments, docxResult, contextMap, flatText, offsetMap);\n }\n } catch (err) {\n ctx.log('Tier 2 DOCX context extraction failed:', err);\n }\n }\n }\n\n // \u2500\u2500 Format comments for display \u2500\u2500\n const formattedComments = comments.map((comment: any, index: number) => {\n const status = comment.resolved ? ' [RESOLVED]' : '';\n const author = comment.author?.displayName || 'Unknown';\n const date = comment.createdTime ? new Date(comment.createdTime).toLocaleDateString() : 'Unknown date';\n const quotedText = comment.quotedFileContent?.value;\n const commentCtx = contextMap.get(comment.id);\n\n let positionInfo = '';\n const indexStr = commentCtx?.startIndex != null\n ? ` [chars ${commentCtx.startIndex}-${commentCtx.endIndex}]` : '';\n\n if (quotedText) {\n const snippet = quotedText.length > 100 ? quotedText.substring(0, 100) + '...' : quotedText;\n positionInfo = `\\n Anchored to: \"${snippet}\"${indexStr}`;\n }\n if (commentCtx) {\n if (commentCtx.contextBefore) positionInfo += `\\n Context before: \"${commentCtx.contextBefore}\"`;\n if (commentCtx.contextAfter) positionInfo += `\\n Context after: \"${commentCtx.contextAfter}\"`;\n }\n\n let result = `${index + 1}. ${author} (${date})${status}${positionInfo}\\n Comment: ${comment.content}`;\n\n if (comment.replies && comment.replies.length > 0) {\n for (const reply of comment.replies) {\n const replyAuthor = reply.author?.displayName || 'Unknown';\n const replyDate = reply.createdTime ? new Date(reply.createdTime).toLocaleDateString() : 'Unknown date';\n const replyContent = reply.content || '(empty)';\n result += `\\n \u2514\u2500 ${replyAuthor} (${replyDate}): ${replyContent}`;\n }\n }\n\n result += `\\n Comment ID: ${comment.id}`;\n return result;\n }).join('\\n\\n');\n\n let text = `Found ${comments.length} comment${comments.length === 1 ? '' : 's'}:\\n\\n${formattedComments}`;\n if (nextPageToken) {\n text += `\\n\\nMore comments available. Use pageToken: \"${nextPageToken}\" to fetch the next page.`;\n }\n\n return {\n content: [{ type: \"text\", text }],\n isError: false\n };\n }\n\n case \"getComment\": {\n const validation = GetCommentSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const response = await ctx.getDrive().comments.get({\n fileId: a.documentId,\n commentId: a.commentId,\n fields: 'id,content,quotedFileContent,author,createdTime,resolved,replies(id,content,author,createdTime)'\n });\n\n const comment = response.data;\n const author = comment.author?.displayName || 'Unknown';\n const date = comment.createdTime ? new Date(comment.createdTime).toLocaleDateString() : 'Unknown date';\n const status = comment.resolved ? ' [RESOLVED]' : '';\n const quotedText = comment.quotedFileContent?.value || 'No quoted text';\n const anchor = quotedText !== 'No quoted text' ? `\\nAnchored to: \"${quotedText}\"` : '';\n\n let result = `${author} (${date})${status}${anchor}\\n${comment.content}`;\n\n if (comment.replies && comment.replies.length > 0) {\n result += '\\n\\nReplies:';\n comment.replies.forEach((reply: any, index: number) => {\n const replyAuthor = reply.author?.displayName || 'Unknown';\n const replyDate = reply.createdTime ? new Date(reply.createdTime).toLocaleDateString() : 'Unknown date';\n result += `\\n${index + 1}. ${replyAuthor} (${replyDate})\\n ${reply.content}`;\n });\n }\n\n return {\n content: [{ type: \"text\", text: result }],\n isError: false\n };\n }\n\n case \"addComment\": {\n const validation = AddCommentSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n if (a.endIndex <= a.startIndex) {\n return errorResponse(\"endIndex must be greater than startIndex\");\n }\n\n // Get the document to extract quoted text\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n const doc = await docs.documents.get({ documentId: a.documentId });\n\n // Extract quoted text from the range\n let quotedText = '';\n const content = doc.data.body?.content || [];\n for (const element of content) {\n if (element.paragraph?.elements) {\n for (const textElement of element.paragraph.elements) {\n if (textElement.textRun) {\n const elementStart = textElement.startIndex || 0;\n const elementEnd = textElement.endIndex || 0;\n\n if (elementEnd > a.startIndex && elementStart < a.endIndex) {\n const text = textElement.textRun.content || '';\n const startOffset = Math.max(0, a.startIndex - elementStart);\n const endOffset = Math.min(text.length, a.endIndex - elementStart);\n quotedText += text.substring(startOffset, endOffset);\n }\n }\n }\n }\n }\n\n const response = await ctx.getDrive().comments.create({\n fileId: a.documentId,\n fields: 'id,content,quotedFileContent,author,createdTime',\n requestBody: {\n content: a.commentText,\n quotedFileContent: {\n value: quotedText,\n mimeType: 'text/html'\n },\n // Reverse-engineered anchor format for positioning comments.\n // Not part of the public Drive API -- may break if Google changes internals.\n // See: https://stackoverflow.com/questions/51789168\n anchor: JSON.stringify({\n r: a.documentId,\n a: [{\n txt: {\n o: a.startIndex - 1, // Drive API uses 0-based indexing\n l: a.endIndex - a.startIndex,\n ml: a.endIndex - a.startIndex\n }\n }]\n })\n }\n });\n\n return {\n content: [{ type: \"text\", text: `Comment added successfully. Comment ID: ${response.data.id}` }],\n isError: false\n };\n }\n\n case \"replyToComment\": {\n const validation = ReplyToCommentSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const response = await ctx.getDrive().replies.create({\n fileId: a.documentId,\n commentId: a.commentId,\n fields: 'id,content,author,createdTime',\n requestBody: {\n content: a.replyText,\n ...(a.resolve && { action: \"resolve\" })\n }\n });\n\n const resolveNote = a.resolve ? ' Comment thread resolved.' : '';\n return {\n content: [{ type: \"text\", text: `Reply added successfully. Reply ID: ${response.data.id}${resolveNote}` }],\n isError: false\n };\n }\n\n case \"deleteComment\": {\n const validation = DeleteCommentSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n await ctx.getDrive().comments.delete({\n fileId: a.documentId,\n commentId: a.commentId\n });\n\n return {\n content: [{ type: \"text\", text: `Comment ${a.commentId} has been deleted.` }],\n isError: false\n };\n }\n\n // =========================================================================\n // TABLE & MEDIA TOOLS\n // =========================================================================\n\n case \"insertTable\": {\n const validation = InsertTableSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const request_body = {\n insertTable: {\n location: { index: a.index },\n rows: a.rows,\n columns: a.columns\n }\n };\n\n await executeBatchUpdate(ctx, a.documentId, [request_body]);\n\n return {\n content: [{ type: \"text\", text: `Successfully inserted ${a.rows}x${a.columns} table at index ${a.index}` }],\n isError: false\n };\n }\n\n case \"editTableCell\": {\n const validation = EditTableCellSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n // Get the document to find the table structure\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n\n const docRes = await docs.documents.get({\n documentId: a.documentId,\n fields: 'body(content)'\n });\n\n // Find the table at the specified start index\n let table: any = null;\n const findTable = (content: any[]) => {\n for (const elem of content) {\n if (elem.table && elem.startIndex === a.tableStartIndex) {\n table = elem.table;\n return;\n }\n }\n };\n\n if (docRes.data.body?.content) {\n findTable(docRes.data.body.content);\n }\n\n if (!table) {\n return errorResponse(`No table found at index ${a.tableStartIndex}`);\n }\n\n // Get the cell\n const row = table.tableRows?.[a.rowIndex];\n if (!row) {\n return errorResponse(`Row ${a.rowIndex} not found in table`);\n }\n\n const cell = row.tableCells?.[a.columnIndex];\n if (!cell) {\n return errorResponse(`Column ${a.columnIndex} not found in row ${a.rowIndex}`);\n }\n\n // Get cell content range\n const cellStartIndex = cell.startIndex;\n const cellEndIndex = cell.endIndex;\n\n const requests: any[] = [];\n\n // If textContent is provided, delete existing content and insert new\n if (a.textContent !== undefined) {\n // Delete existing content (keeping the paragraph structure)\n const cellContentStart = cellStartIndex + 1; // Skip the cell start marker\n const cellContentEnd = cellEndIndex - 1; // Before cell end marker\n\n if (cellContentEnd > cellContentStart) {\n requests.push({\n deleteContentRange: {\n range: { startIndex: cellContentStart, endIndex: cellContentEnd }\n }\n });\n }\n\n // Insert new text\n if (a.textContent.length > 0) {\n requests.push({\n insertText: {\n location: { index: cellContentStart },\n text: a.textContent\n }\n });\n }\n }\n\n // Apply text styling if any style options provided\n if (a.bold !== undefined || a.italic !== undefined || a.fontSize !== undefined) {\n const textStyle: any = {};\n const fields: string[] = [];\n\n if (a.bold !== undefined) { textStyle.bold = a.bold; fields.push('bold'); }\n if (a.italic !== undefined) { textStyle.italic = a.italic; fields.push('italic'); }\n if (a.fontSize !== undefined) { textStyle.fontSize = { magnitude: a.fontSize, unit: 'PT' }; fields.push('fontSize'); }\n\n if (fields.length > 0) {\n // Apply to the cell content range\n const styleStart = cellStartIndex + 1;\n const styleEnd = a.textContent !== undefined\n ? styleStart + a.textContent.length\n : cellEndIndex - 1;\n\n requests.push({\n updateTextStyle: {\n range: { startIndex: styleStart, endIndex: styleEnd },\n textStyle,\n fields: fields.join(',')\n }\n });\n }\n }\n\n // Apply paragraph alignment if provided\n if (a.alignment !== undefined) {\n requests.push({\n updateParagraphStyle: {\n range: { startIndex: cellStartIndex + 1, endIndex: cellEndIndex - 1 },\n paragraphStyle: { alignment: a.alignment },\n fields: 'alignment'\n }\n });\n }\n\n if (requests.length === 0) {\n return errorResponse(\"No changes specified for the table cell\");\n }\n\n await executeBatchUpdate(ctx, a.documentId, requests);\n\n return {\n content: [{ type: \"text\", text: `Successfully edited cell at row ${a.rowIndex}, column ${a.columnIndex}` }],\n isError: false\n };\n }\n\n case \"insertImageFromUrl\": {\n const validation = InsertImageFromUrlSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n await insertInlineImageHelper(ctx, a.documentId, a.imageUrl, a.index, a.width, a.height);\n\n return {\n content: [{ type: \"text\", text: `Successfully inserted image from URL at index ${a.index}` }],\n isError: false\n };\n }\n\n case \"insertLocalImage\": {\n const validation = InsertLocalImageSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n // Get the document's parent folder if uploadToSameFolder is true\n let parentFolderId: string | undefined;\n if (a.uploadToSameFolder !== false) {\n const fileInfo = await ctx.getDrive().files.get({\n fileId: a.documentId,\n fields: 'parents',\n supportsAllDrives: true\n });\n parentFolderId = fileInfo.data.parents?.[0];\n }\n\n // Upload the image to Drive\n const { webContentLink: imageUrl } = await uploadImageToDrive(ctx, a.localImagePath, {\n parentFolderId,\n makePublic: a.makePublic,\n });\n\n // Insert the image into the document\n await insertInlineImageHelper(ctx, a.documentId, imageUrl, a.index, a.width, a.height);\n\n return {\n content: [{ type: \"text\", text: `Successfully uploaded and inserted local image at index ${a.index}\\nImage URL: ${imageUrl}` }],\n isError: false\n };\n }\n\n // =========================================================================\n // GOOGLE DOCS DISCOVERY & MANAGEMENT TOOLS\n // =========================================================================\n\n case \"listGoogleDocs\": {\n const validation = ListGoogleDocsSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n // Build the query string for Google Drive API\n let queryString = \"mimeType='application/vnd.google-apps.document' and trashed=false\";\n if (a.query) {\n const escapedQuery = escapeDriveQuery(a.query);\n queryString += ` and (name contains '${escapedQuery}' or fullText contains '${escapedQuery}')`;\n }\n\n const response = await ctx.getDrive().files.list({\n q: queryString,\n pageSize: a.maxResults,\n orderBy: a.orderBy === 'name' ? 'name' : a.orderBy,\n fields: 'files(id,name,modifiedTime,createdTime,size,webViewLink,owners(displayName,emailAddress))',\n supportsAllDrives: true,\n includeItemsFromAllDrives: true\n });\n\n const files = response.data.files || [];\n\n if (files.length === 0) {\n return { content: [{ type: \"text\", text: \"No Google Docs found matching your criteria.\" }], isError: false };\n }\n\n let result = `Found ${files.length} Google Document(s):\\n\\n`;\n for (let i = 0; i < files.length; i++) {\n const file = files[i];\n const modifiedDate = file.modifiedTime ? new Date(file.modifiedTime).toLocaleDateString() : 'Unknown';\n const owner = file.owners?.[0]?.displayName || 'Unknown';\n result += `${i + 1}. **${file.name}**\\n`;\n result += ` ID: ${file.id}\\n`;\n result += ` Modified: ${modifiedDate}\\n`;\n result += ` Owner: ${owner}\\n`;\n result += ` Link: ${file.webViewLink}\\n\\n`;\n }\n\n return { content: [{ type: \"text\", text: result }], isError: false };\n }\n\n case \"getDocumentInfo\": {\n const validation = GetDocumentInfoSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const response = await ctx.getDrive().files.get({\n fileId: a.documentId,\n fields: 'id,name,description,mimeType,size,createdTime,modifiedTime,webViewLink,owners(displayName,emailAddress),lastModifyingUser(displayName,emailAddress),shared,parents,version',\n });\n\n const file = response.data;\n\n if (!file) {\n return errorResponse(`Document with ID ${a.documentId} not found.`);\n }\n\n const createdDate = file.createdTime ? new Date(file.createdTime).toLocaleString() : 'Unknown';\n const modifiedDate = file.modifiedTime ? new Date(file.modifiedTime).toLocaleString() : 'Unknown';\n const owner = file.owners?.[0];\n const lastModifier = (file as any).lastModifyingUser;\n\n let result = `**Document Information:**\\n\\n`;\n result += `**Name:** ${file.name}\\n`;\n result += `**ID:** ${file.id}\\n`;\n result += `**Type:** Google Document\\n`;\n result += `**Created:** ${createdDate}\\n`;\n result += `**Last Modified:** ${modifiedDate}\\n`;\n\n if (owner) {\n result += `**Owner:** ${owner.displayName} (${owner.emailAddress})\\n`;\n }\n\n if (lastModifier) {\n result += `**Last Modified By:** ${lastModifier.displayName} (${lastModifier.emailAddress})\\n`;\n }\n\n if (file.description) {\n result += `**Description:** ${file.description}\\n`;\n }\n\n result += `**Shared:** ${file.shared ? 'Yes' : 'No'}\\n`;\n result += `**Version:** ${file.version || 'Unknown'}\\n`;\n result += `**View Link:** ${file.webViewLink}\\n`;\n\n return { content: [{ type: \"text\", text: result }], isError: false };\n }\n\n case \"addDocumentTab\": {\n const validation = AddDocumentTabSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const a = validation.data;\n\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n await docs.documents.batchUpdate({\n documentId: a.documentId,\n // addDocumentTab is not yet in the googleapis TypeScript types \u2014 cast required\n requestBody: { requests: [{ addDocumentTab: { tabProperties: { title: a.title } } } as any] }\n });\n\n return { content: [{ type: 'text', text: `Requested creation of tab \"${a.title}\" in document ${a.documentId}.` }], isError: false };\n }\n\n case \"renameDocumentTab\": {\n const validation = RenameDocumentTabSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const a = validation.data;\n\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n await docs.documents.batchUpdate({\n documentId: a.documentId,\n // updateDocumentTabProperties is not yet in the googleapis TypeScript types \u2014 cast required.\n // Per Google Docs API spec: tabId lives INSIDE tabProperties (it's the tab identifier),\n // and `fields` is a FieldMask for which properties to update (excludes tabId).\n requestBody: { requests: [{ updateDocumentTabProperties: { tabProperties: { tabId: a.tabId, title: a.title }, fields: 'title' } } as any] }\n });\n\n return { content: [{ type: 'text', text: `Renamed tab ${a.tabId} to \"${a.title}\".` }], isError: false };\n }\n\n case \"insertSmartChip\": {\n const validation = InsertSmartChipSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const a = validation.data;\n\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n await docs.documents.batchUpdate({\n documentId: a.documentId,\n requestBody: {\n requests: [{\n insertPerson: {\n personProperties: { email: a.personEmail },\n location: { index: a.index },\n },\n // insertPerson is not yet in the googleapis TypeScript types \u2014 cast required\n } as any],\n },\n });\n\n return { content: [{ type: 'text', text: `Inserted person smart chip for ${a.personEmail} at index ${a.index}.` }], isError: false };\n }\n\n case \"readSmartChips\": {\n const validation = ReadSmartChipsSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const a = validation.data;\n\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n const doc = await docs.documents.get({ documentId: a.documentId });\n const body = (doc.data as any).body?.content || [];\n const hits: string[] = [];\n for (const block of body) {\n for (const el of block?.paragraph?.elements || []) {\n if (el?.richLink) hits.push(`richLink: ${el.richLink.richLinkProperties?.uri || 'unknown'}`);\n if (el?.person) hits.push(`person: ${el.person.personProperties?.email || 'unknown'}`);\n }\n }\n // Date chips appear as richLink elements in the Docs API model \u2014 already covered above.\n return { content: [{ type: 'text', text: hits.length ? hits.join('\\n') : 'No smart chips detected (note: only the default tab is scanned).' }], isError: false };\n }\n\n case \"createFootnote\": {\n const validation = CreateFootnoteSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const a = validation.data;\n\n const docs = ctx.google.docs({ version: 'v1', auth: ctx.authClient });\n\n // Build the createFootnote request\n const createFootnoteReq: { location?: { index: number }; endOfSegmentLocation?: { segmentId: string } } = {};\n if (a.index !== undefined) {\n createFootnoteReq.location = { index: a.index };\n } else {\n createFootnoteReq.endOfSegmentLocation = { segmentId: \"\" };\n }\n\n const res = await docs.documents.batchUpdate({\n documentId: a.documentId,\n requestBody: {\n requests: [{ createFootnote: createFootnoteReq }],\n },\n });\n\n const footnoteId = res.data.replies?.[0]?.createFootnote?.footnoteId;\n if (!footnoteId) {\n return errorResponse(\"Failed to create footnote \u2014 no footnoteId in response.\");\n }\n\n const locationDesc = a.index !== undefined ? `at index ${a.index}` : 'at end of document';\n\n // Optionally insert text content into the footnote body\n if (a.content) {\n try {\n await docs.documents.batchUpdate({\n documentId: a.documentId,\n requestBody: {\n requests: [{\n insertText: {\n location: { segmentId: footnoteId, index: 0 },\n text: a.content,\n },\n }],\n },\n });\n } catch (err: any) {\n return { content: [{ type: 'text', text: `Created footnote ${footnoteId} ${locationDesc}, but failed to insert content: ${err.message}` }], isError: true };\n }\n }\n\n return { content: [{ type: 'text', text: `Created footnote ${footnoteId} ${locationDesc}.${a.content ? ' Content inserted.' : ''}` }], isError: false };\n }\n\n default:\n return null;\n }\n}\n", "import { existsSync, createReadStream } from 'fs';\nimport { basename, extname } from 'path';\nimport type { ToolContext } from '../types.js';\n\nconst MIME_BY_EXT: { [ext: string]: string } = {\n '.jpg': 'image/jpeg',\n '.jpeg': 'image/jpeg',\n '.png': 'image/png',\n '.gif': 'image/gif',\n '.bmp': 'image/bmp',\n '.webp': 'image/webp',\n '.svg': 'image/svg+xml',\n};\n\nexport interface UploadedImage {\n fileId: string;\n webContentLink: string;\n}\n\nexport async function uploadImageToDrive(\n ctx: ToolContext,\n localFilePath: string,\n options: { parentFolderId?: string; makePublic?: boolean } = {},\n): Promise<UploadedImage> {\n const { parentFolderId, makePublic = false } = options;\n\n if (!existsSync(localFilePath)) {\n throw new Error(`Image file not found: ${localFilePath}`);\n }\n\n const fileName = basename(localFilePath);\n const ext = extname(localFilePath).toLowerCase();\n const mimeType = MIME_BY_EXT[ext] || 'application/octet-stream';\n\n const requestBody: { name: string; mimeType: string; parents?: string[] } = {\n name: fileName,\n mimeType,\n };\n if (parentFolderId) requestBody.parents = [parentFolderId];\n\n const drive = ctx.getDrive();\n\n const uploadResponse = await drive.files.create({\n requestBody,\n media: { mimeType, body: createReadStream(localFilePath) },\n fields: 'id,webViewLink,webContentLink',\n supportsAllDrives: true,\n });\n\n const fileId = uploadResponse.data.id;\n if (!fileId) throw new Error('Failed to upload image to Drive - no file ID returned');\n\n if (makePublic) {\n await drive.permissions.create({\n fileId,\n requestBody: { role: 'reader', type: 'anyone' },\n });\n }\n\n const fileInfo = await drive.files.get({\n fileId,\n fields: 'webContentLink',\n supportsAllDrives: true,\n });\n\n const webContentLink = fileInfo.data.webContentLink;\n if (!webContentLink) throw new Error('Failed to get web content link for uploaded image');\n\n return { fileId, webContentLink };\n}\n\nexport async function deleteDriveFile(ctx: ToolContext, fileId: string): Promise<void> {\n await ctx.getDrive().files.delete({ fileId, supportsAllDrives: true });\n}\n", "import { z } from 'zod';\nimport type { ToolDefinition, ToolResult, ToolContext } from '../types.js';\nimport { errorResponse } from '../types.js';\nimport { parseA1Range, convertA1ToGridRange, escapeDriveQuery, type GridRange } from '../utils.js';\n\n// ---------------------------------------------------------------------------\n// Zod Schemas\n// ---------------------------------------------------------------------------\n\nconst CreateGoogleSheetSchema = z.object({\n name: z.string().min(1, \"Sheet name is required\"),\n data: z.array(z.array(z.string())),\n parentFolderId: z.string().optional(),\n valueInputOption: z.enum([\"RAW\", \"USER_ENTERED\"]).optional()\n});\n\nconst UpdateGoogleSheetSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n range: z.string().min(1, \"Range is required\"),\n data: z.array(z.array(z.string())),\n valueInputOption: z.enum([\"RAW\", \"USER_ENTERED\"]).optional()\n});\n\nconst GetGoogleSheetContentSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n range: z.string().min(1, \"Range is required\")\n});\n\nconst FormatGoogleSheetCellsSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n range: z.string().min(1, \"Range is required\"),\n backgroundColor: z.object({\n red: z.number().min(0).max(1).optional(),\n green: z.number().min(0).max(1).optional(),\n blue: z.number().min(0).max(1).optional()\n }).optional(),\n horizontalAlignment: z.enum([\"LEFT\", \"CENTER\", \"RIGHT\"]).optional(),\n verticalAlignment: z.enum([\"TOP\", \"MIDDLE\", \"BOTTOM\"]).optional(),\n wrapStrategy: z.enum([\"OVERFLOW_CELL\", \"CLIP\", \"WRAP\"]).optional()\n});\n\nconst FormatGoogleSheetTextSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n range: z.string().min(1, \"Range is required\"),\n bold: z.boolean().optional(),\n italic: z.boolean().optional(),\n strikethrough: z.boolean().optional(),\n underline: z.boolean().optional(),\n fontSize: z.number().min(1).optional(),\n fontFamily: z.string().optional(),\n foregroundColor: z.object({\n red: z.number().min(0).max(1).optional(),\n green: z.number().min(0).max(1).optional(),\n blue: z.number().min(0).max(1).optional()\n }).optional()\n});\n\nconst FormatGoogleSheetNumbersSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n range: z.string().min(1, \"Range is required\"),\n pattern: z.string().min(1, \"Pattern is required\"),\n type: z.enum([\"NUMBER\", \"CURRENCY\", \"PERCENT\", \"DATE\", \"TIME\", \"DATE_TIME\", \"SCIENTIFIC\"]).optional()\n});\n\nconst SetGoogleSheetBordersSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n range: z.string().min(1, \"Range is required\"),\n style: z.enum([\"SOLID\", \"DASHED\", \"DOTTED\", \"DOUBLE\"]),\n width: z.number().min(1).max(3).optional(),\n color: z.object({\n red: z.number().min(0).max(1).optional(),\n green: z.number().min(0).max(1).optional(),\n blue: z.number().min(0).max(1).optional()\n }).optional(),\n top: z.boolean().optional(),\n bottom: z.boolean().optional(),\n left: z.boolean().optional(),\n right: z.boolean().optional(),\n innerHorizontal: z.boolean().optional(),\n innerVertical: z.boolean().optional()\n});\n\nconst MergeGoogleSheetCellsSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n range: z.string().min(1, \"Range is required\"),\n mergeType: z.enum([\"MERGE_ALL\", \"MERGE_COLUMNS\", \"MERGE_ROWS\"])\n});\n\nconst AddGoogleSheetConditionalFormatSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n range: z.string().min(1, \"Range is required\"),\n condition: z.object({\n type: z.enum([\"NUMBER_GREATER\", \"NUMBER_LESS\", \"TEXT_CONTAINS\", \"TEXT_STARTS_WITH\", \"TEXT_ENDS_WITH\", \"CUSTOM_FORMULA\"]),\n value: z.string()\n }),\n format: z.object({\n backgroundColor: z.object({\n red: z.number().min(0).max(1).optional(),\n green: z.number().min(0).max(1).optional(),\n blue: z.number().min(0).max(1).optional()\n }).optional(),\n textFormat: z.object({\n bold: z.boolean().optional(),\n foregroundColor: z.object({\n red: z.number().min(0).max(1).optional(),\n green: z.number().min(0).max(1).optional(),\n blue: z.number().min(0).max(1).optional()\n }).optional()\n }).optional()\n })\n});\n\nconst GetSpreadsheetInfoSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\")\n});\n\nconst AppendSpreadsheetRowsSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n range: z.string().min(1, \"Range is required\"),\n values: z.array(z.array(z.any())),\n valueInputOption: z.enum([\"RAW\", \"USER_ENTERED\"]).optional().default(\"USER_ENTERED\")\n});\n\nconst AddSpreadsheetSheetSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n sheetTitle: z.string().min(1, \"Sheet title is required\")\n});\n\nconst AddSheetSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n title: z.string().min(1, \"Sheet title is required\")\n});\n\nconst ListSheetsSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\")\n});\n\nconst RenameSheetSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n sheetId: z.number().int(),\n newTitle: z.string().min(1, \"New title is required\")\n});\n\nconst DeleteSheetSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n sheetId: z.number().int()\n});\n\nconst AddDataValidationSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n range: z.string().min(1, \"Range is required\"),\n conditionType: z.enum([\"ONE_OF_LIST\", \"NUMBER_GREATER\", \"NUMBER_LESS\", \"TEXT_CONTAINS\"]),\n values: z.array(z.string()).min(1, \"At least one value is required\"),\n strict: z.boolean().optional().default(true),\n showCustomUi: z.boolean().optional().default(true)\n});\n\nconst ProtectRangeSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n range: z.string().min(1, \"Range is required\"),\n description: z.string().optional(),\n warningOnly: z.boolean().optional().default(false)\n});\n\nconst AddNamedRangeSchema = z.object({\n spreadsheetId: z.string().min(1, \"Spreadsheet ID is required\"),\n name: z.string().min(1, \"Name is required\"),\n range: z.string().min(1, \"Range is required\")\n});\n\nconst ListGoogleSheetsSchema = z.object({\n maxResults: z.number().int().min(1).max(100).optional().default(20),\n query: z.string().optional(),\n orderBy: z.enum([\"name\", \"modifiedTime\", \"createdTime\"]).optional().default(\"modifiedTime\")\n});\n\n// ---------------------------------------------------------------------------\n// Tool Definitions\n// ---------------------------------------------------------------------------\n\nexport const toolDefinitions: ToolDefinition[] = [\n {\n name: \"createGoogleSheet\",\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.\",\n inputSchema: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"Sheet name\" },\n data: {\n type: \"array\",\n description: \"Data as array of arrays\",\n items: { type: \"array\", items: { type: \"string\" } }\n },\n parentFolderId: { type: \"string\", description: \"Parent folder ID (defaults to root)\" },\n valueInputOption: {\n type: \"string\",\n enum: [\"RAW\", \"USER_ENTERED\"],\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().\"\n }\n },\n required: [\"name\", \"data\"]\n }\n },\n {\n name: \"updateGoogleSheet\",\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.\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Sheet ID\" },\n range: { type: \"string\", description: \"Range to update (e.g., 'Sheet1!A1:C10')\" },\n data: {\n type: \"array\",\n description: \"2D array of values to write\",\n items: { type: \"array\", items: { type: \"string\" } }\n },\n valueInputOption: {\n type: \"string\",\n enum: [\"RAW\", \"USER_ENTERED\"],\n description: \"RAW (default): Values stored exactly as provided - formulas stored as text strings. Safe for untrusted data. USER_ENTERED: Values parsed like spreadsheet UI - formulas (=SUM, =IF, etc.) are evaluated. SECURITY WARNING: USER_ENTERED can execute formulas, only use with trusted data, never with user-provided input that could contain malicious formulas like =IMPORTDATA() or =IMPORTRANGE().\"\n }\n },\n required: [\"spreadsheetId\", \"range\", \"data\"]\n }\n },\n {\n name: \"getGoogleSheetContent\",\n description: \"Get content of a Google Sheet with cell information\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\n range: { type: \"string\", description: \"Range to get (e.g., 'Sheet1!A1:C10')\" }\n },\n required: [\"spreadsheetId\", \"range\"]\n }\n },\n {\n name: \"formatGoogleSheetCells\",\n description: \"Format cells in a Google Sheet (background, borders, alignment)\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\n range: { type: \"string\", description: \"Range to format (e.g., 'A1:C10')\" },\n backgroundColor: {\n type: \"object\",\n description: \"Background color (RGB values 0-1)\",\n properties: {\n red: { type: \"number\" },\n green: { type: \"number\" },\n blue: { type: \"number\" }\n }\n },\n horizontalAlignment: {\n type: \"string\",\n description: \"Horizontal alignment\",\n enum: [\"LEFT\", \"CENTER\", \"RIGHT\"]\n },\n verticalAlignment: {\n type: \"string\",\n description: \"Vertical alignment\",\n enum: [\"TOP\", \"MIDDLE\", \"BOTTOM\"]\n },\n wrapStrategy: {\n type: \"string\",\n description: \"Text wrapping\",\n enum: [\"OVERFLOW_CELL\", \"CLIP\", \"WRAP\"]\n }\n },\n required: [\"spreadsheetId\", \"range\"]\n }\n },\n {\n name: \"formatGoogleSheetText\",\n description: \"Apply text formatting to cells in a Google Sheet\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\n range: { type: \"string\", description: \"Range to format (e.g., 'A1:C10')\" },\n bold: { type: \"boolean\", description: \"Make text bold\" },\n italic: { type: \"boolean\", description: \"Make text italic\" },\n strikethrough: { type: \"boolean\", description: \"Strikethrough text\" },\n underline: { type: \"boolean\", description: \"Underline text\" },\n fontSize: { type: \"number\", description: \"Font size in points\" },\n fontFamily: { type: \"string\", description: \"Font family name\" },\n foregroundColor: {\n type: \"object\",\n description: \"Text color (RGB values 0-1)\",\n properties: {\n red: { type: \"number\" },\n green: { type: \"number\" },\n blue: { type: \"number\" }\n }\n }\n },\n required: [\"spreadsheetId\", \"range\"]\n }\n },\n {\n name: \"formatGoogleSheetNumbers\",\n description: \"Apply number formatting to cells in a Google Sheet\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\n range: { type: \"string\", description: \"Range to format (e.g., 'A1:C10')\" },\n pattern: {\n type: \"string\",\n description: \"Number format pattern (e.g., '#,##0.00', 'yyyy-mm-dd', '$#,##0.00', '0.00%')\"\n },\n type: {\n type: \"string\",\n description: \"Format type\",\n enum: [\"NUMBER\", \"CURRENCY\", \"PERCENT\", \"DATE\", \"TIME\", \"DATE_TIME\", \"SCIENTIFIC\"]\n }\n },\n required: [\"spreadsheetId\", \"range\", \"pattern\"]\n }\n },\n {\n name: \"setGoogleSheetBorders\",\n description: \"Set borders for cells in a Google Sheet\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\n range: { type: \"string\", description: \"Range to format (e.g., 'A1:C10')\" },\n style: {\n type: \"string\",\n description: \"Border style\",\n enum: [\"SOLID\", \"DASHED\", \"DOTTED\", \"DOUBLE\"]\n },\n width: { type: \"number\", description: \"Border width (1-3)\" },\n color: {\n type: \"object\",\n description: \"Border color (RGB values 0-1)\",\n properties: {\n red: { type: \"number\" },\n green: { type: \"number\" },\n blue: { type: \"number\" }\n }\n },\n top: { type: \"boolean\", description: \"Apply to top border\" },\n bottom: { type: \"boolean\", description: \"Apply to bottom border\" },\n left: { type: \"boolean\", description: \"Apply to left border\" },\n right: { type: \"boolean\", description: \"Apply to right border\" },\n innerHorizontal: { type: \"boolean\", description: \"Apply to inner horizontal borders\" },\n innerVertical: { type: \"boolean\", description: \"Apply to inner vertical borders\" }\n },\n required: [\"spreadsheetId\", \"range\", \"style\"]\n }\n },\n {\n name: \"mergeGoogleSheetCells\",\n description: \"Merge cells in a Google Sheet\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\n range: { type: \"string\", description: \"Range to merge (e.g., 'A1:C3')\" },\n mergeType: {\n type: \"string\",\n description: \"Merge type\",\n enum: [\"MERGE_ALL\", \"MERGE_COLUMNS\", \"MERGE_ROWS\"]\n }\n },\n required: [\"spreadsheetId\", \"range\", \"mergeType\"]\n }\n },\n {\n name: \"addGoogleSheetConditionalFormat\",\n description: \"Add conditional formatting to a Google Sheet\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\n range: { type: \"string\", description: \"Range to apply formatting (e.g., 'A1:C10')\" },\n condition: {\n type: \"object\",\n description: \"Condition configuration\",\n properties: {\n type: {\n type: \"string\",\n description: \"Condition type\",\n enum: [\"NUMBER_GREATER\", \"NUMBER_LESS\", \"TEXT_CONTAINS\", \"TEXT_STARTS_WITH\", \"TEXT_ENDS_WITH\", \"CUSTOM_FORMULA\"]\n },\n value: { type: \"string\", description: \"Value to compare or formula\" }\n }\n },\n format: {\n type: \"object\",\n description: \"Format to apply when condition is true\",\n properties: {\n backgroundColor: {\n type: \"object\",\n properties: {\n red: { type: \"number\" },\n green: { type: \"number\" },\n blue: { type: \"number\" }\n }\n },\n textFormat: {\n type: \"object\",\n properties: {\n bold: { type: \"boolean\" },\n foregroundColor: {\n type: \"object\",\n properties: {\n red: { type: \"number\" },\n green: { type: \"number\" },\n blue: { type: \"number\" }\n }\n }\n }\n }\n }\n }\n },\n required: [\"spreadsheetId\", \"range\", \"condition\", \"format\"]\n }\n },\n {\n name: \"getSpreadsheetInfo\",\n description: \"Gets detailed information about a Google Spreadsheet including all sheets/tabs\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"The ID of the Google Spreadsheet (from the URL)\" }\n },\n required: [\"spreadsheetId\"]\n }\n },\n {\n name: \"appendSpreadsheetRows\",\n description: \"Appends rows of data to the end of a sheet in a Google Spreadsheet\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"The ID of the Google Spreadsheet (from the URL)\" },\n range: { type: \"string\", description: \"A1 notation range indicating where to append (e.g., 'A1' or 'Sheet1!A1'). Data will be appended starting from this range.\" },\n values: {\n type: \"array\",\n description: \"2D array of values to append. Each inner array represents a row.\",\n items: {\n type: \"array\",\n items: {\n anyOf: [\n { type: \"string\" },\n { type: \"number\" },\n { type: \"boolean\" },\n { type: \"null\" }\n ]\n }\n }\n },\n valueInputOption: { type: \"string\", description: \"How input data should be interpreted (RAW or USER_ENTERED)\", enum: [\"RAW\", \"USER_ENTERED\"], default: \"USER_ENTERED\" }\n },\n required: [\"spreadsheetId\", \"range\", \"values\"]\n }\n },\n {\n name: \"addSpreadsheetSheet\",\n description: \"Adds a new sheet/tab to an existing Google Spreadsheet\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"The ID of the Google Spreadsheet (from the URL)\" },\n sheetTitle: { type: \"string\", description: \"Title for the new sheet/tab\" }\n },\n required: [\"spreadsheetId\", \"sheetTitle\"]\n }\n },\n {\n name: \"addSheet\",\n description: \"Alias for addSpreadsheetSheet (adds a new sheet/tab)\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\n title: { type: \"string\", description: \"Title for the new sheet/tab\" }\n },\n required: [\"spreadsheetId\", \"title\"]\n }\n },\n {\n name: \"listSheets\",\n description: \"List tabs/sheets in a Google Spreadsheet\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" }\n },\n required: [\"spreadsheetId\"]\n }\n },\n {\n name: \"renameSheet\",\n description: \"Rename a sheet/tab by sheetId\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\n sheetId: { type: \"number\", description: \"Sheet ID\" },\n newTitle: { type: \"string\", description: \"New title\" }\n },\n required: [\"spreadsheetId\", \"sheetId\", \"newTitle\"]\n }\n },\n {\n name: \"deleteSheet\",\n description: \"Delete a sheet/tab by sheetId\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\n sheetId: { type: \"number\", description: \"Sheet ID\" }\n },\n required: [\"spreadsheetId\", \"sheetId\"]\n }\n },\n {\n name: \"addDataValidation\",\n description: \"Add data validation rules to a sheet range\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\n range: { type: \"string\", description: \"A1 range\" },\n conditionType: { type: \"string\", enum: [\"ONE_OF_LIST\", \"NUMBER_GREATER\", \"NUMBER_LESS\", \"TEXT_CONTAINS\"], description: \"Validation condition type\" },\n values: { type: \"array\", items: { type: \"string\" }, description: \"Condition values (e.g. list items, threshold)\" },\n strict: { type: \"boolean\", description: \"Reject invalid values\" },\n showCustomUi: { type: \"boolean\", description: \"Show dropdown/custom UI\" }\n },\n required: [\"spreadsheetId\", \"range\", \"conditionType\", \"values\"]\n }\n },\n {\n name: \"protectRange\",\n description: \"Protect a range in a spreadsheet\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\n range: { type: \"string\", description: \"A1 range\" },\n description: { type: \"string\", description: \"Protection description\" },\n warningOnly: { type: \"boolean\", description: \"Warn instead of enforce\" }\n },\n required: [\"spreadsheetId\", \"range\"]\n }\n },\n {\n name: \"addNamedRange\",\n description: \"Create a named range\",\n inputSchema: {\n type: \"object\",\n properties: {\n spreadsheetId: { type: \"string\", description: \"Spreadsheet ID\" },\n name: { type: \"string\", description: \"Named range name\" },\n range: { type: \"string\", description: \"A1 range\" }\n },\n required: [\"spreadsheetId\", \"name\", \"range\"]\n }\n },\n {\n name: \"listGoogleSheets\",\n description: \"Lists Google Spreadsheets from your Google Drive with optional filtering\",\n inputSchema: {\n type: \"object\",\n properties: {\n maxResults: { type: \"number\", description: \"Maximum number of spreadsheets to return (1-100)\", default: 20 },\n query: { type: \"string\", description: \"Search query to filter spreadsheets by name or content\" },\n orderBy: { type: \"string\", description: \"Sort order for results\", enum: [\"name\", \"modifiedTime\", \"createdTime\"], default: \"modifiedTime\" }\n },\n required: []\n }\n }\n];\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nasync function resolveGridRange(\n sheetsService: ReturnType<ToolContext['google']['sheets']>,\n spreadsheetId: string,\n range: string\n): Promise<GridRange | string> {\n const rangeData = await sheetsService.spreadsheets.get({\n spreadsheetId,\n ranges: [range],\n fields: 'sheets(properties(sheetId,title))'\n });\n const { sheetName, cellRange: a1Range } = parseA1Range(range);\n const sheet = rangeData.data.sheets?.find(s => s.properties?.title === sheetName);\n if (!sheet || sheet.properties?.sheetId === undefined || sheet.properties?.sheetId === null) {\n return `Sheet \"${sheetName}\" not found`;\n }\n return convertA1ToGridRange(a1Range, sheet.properties.sheetId!);\n}\n\n// ---------------------------------------------------------------------------\n// Handler\n// ---------------------------------------------------------------------------\n\nexport async function handleTool(\n toolName: string,\n args: Record<string, unknown>,\n ctx: ToolContext\n): Promise<ToolResult | null> {\n switch (toolName) {\n case \"createGoogleSheet\": {\n const validation = CreateGoogleSheetSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const parentFolderId = await ctx.resolveFolderId(a.parentFolderId);\n\n // Check if spreadsheet already exists\n const existingFileId = await ctx.checkFileExists(a.name, parentFolderId);\n if (existingFileId) {\n return errorResponse(\n `A spreadsheet named \"${a.name}\" already exists in this location. ` +\n `To update it, use updateGoogleSheet with spreadsheetId: ${existingFileId}`\n );\n }\n const sheets = ctx.google.sheets({ version: 'v4', auth: ctx.authClient });\n\n // Create spreadsheet with initial sheet\n const spreadsheet = await sheets.spreadsheets.create({\n requestBody: {\n properties: { title: a.name },\n sheets: [{\n properties: {\n sheetId: 0,\n title: 'Sheet1',\n gridProperties: {\n rowCount: Math.max(a.data.length, 1000),\n columnCount: Math.max(a.data[0]?.length || 0, 26)\n }\n }\n }]\n }\n });\n\n await ctx.getDrive().files.update({\n fileId: spreadsheet.data.spreadsheetId || '',\n addParents: parentFolderId,\n removeParents: 'root',\n fields: 'id, name, webViewLink',\n supportsAllDrives: true\n });\n\n // Now update with data\n await sheets.spreadsheets.values.update({\n spreadsheetId: spreadsheet.data.spreadsheetId!,\n range: 'Sheet1!A1',\n valueInputOption: a.valueInputOption || 'RAW',\n requestBody: { values: a.data }\n });\n\n return {\n content: [{ type: \"text\", text: `Created Google Sheet: ${a.name}\\nID: ${spreadsheet.data.spreadsheetId}` }],\n isError: false\n };\n }\n\n case \"updateGoogleSheet\": {\n const validation = UpdateGoogleSheetSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const sheets = ctx.google.sheets({ version: 'v4', auth: ctx.authClient });\n await sheets.spreadsheets.values.update({\n spreadsheetId: a.spreadsheetId,\n range: a.range,\n valueInputOption: a.valueInputOption || 'RAW',\n requestBody: { values: a.data }\n });\n\n return {\n content: [{ type: \"text\", text: `Updated Google Sheet range: ${a.range}` }],\n isError: false\n };\n }\n\n case \"getGoogleSheetContent\": {\n const validation = GetGoogleSheetContentSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const sheets = ctx.google.sheets({ version: 'v4', auth: ctx.authClient });\n const response = await sheets.spreadsheets.values.get({\n spreadsheetId: a.spreadsheetId,\n range: a.range\n });\n\n const values = response.data.values || [];\n let content = `Content for range ${a.range}:\\n\\n`;\n\n if (values.length === 0) {\n content += \"(empty range)\";\n } else {\n values.forEach((row, rowIndex) => {\n content += `Row ${rowIndex + 1}: ${row.join(', ')}\\n`;\n });\n }\n\n return {\n content: [{ type: \"text\", text: content }],\n isError: false\n };\n }\n\n case \"formatGoogleSheetCells\": {\n const validation = FormatGoogleSheetCellsSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const sheets = ctx.google.sheets({ version: 'v4', auth: ctx.authClient });\n\n // Parse the range to get sheet ID and grid range\n const rangeData = await sheets.spreadsheets.get({\n spreadsheetId: a.spreadsheetId,\n ranges: [a.range],\n fields: 'sheets(properties(sheetId,title))'\n });\n\n const { sheetName, cellRange: a1Range } = parseA1Range(a.range);\n\n const sheet = rangeData.data.sheets?.find(s => s.properties?.title === sheetName);\n\n if (!sheet || sheet.properties?.sheetId === undefined || sheet.properties?.sheetId === null) {\n return errorResponse(`Sheet \"${sheetName}\" not found`);\n }\n\n // Parse A1 notation to grid range\n const gridRange = convertA1ToGridRange(a1Range, sheet.properties.sheetId!);\n\n const requests: any[] = [{\n repeatCell: {\n range: gridRange,\n cell: {\n userEnteredFormat: {\n ...(a.backgroundColor && {\n backgroundColor: {\n red: a.backgroundColor.red || 0,\n green: a.backgroundColor.green || 0,\n blue: a.backgroundColor.blue || 0\n }\n }),\n ...(a.horizontalAlignment && { horizontalAlignment: a.horizontalAlignment }),\n ...(a.verticalAlignment && { verticalAlignment: a.verticalAlignment }),\n ...(a.wrapStrategy && { wrapStrategy: a.wrapStrategy })\n }\n },\n fields: [\n a.backgroundColor && 'userEnteredFormat.backgroundColor',\n a.horizontalAlignment && 'userEnteredFormat.horizontalAlignment',\n a.verticalAlignment && 'userEnteredFormat.verticalAlignment',\n a.wrapStrategy && 'userEnteredFormat.wrapStrategy'\n ].filter(Boolean).join(',')\n }\n }];\n\n await sheets.spreadsheets.batchUpdate({\n spreadsheetId: a.spreadsheetId,\n requestBody: { requests }\n });\n\n return {\n content: [{ type: \"text\", text: `Formatted cells in range ${a.range}` }],\n isError: false\n };\n }\n\n case \"formatGoogleSheetText\": {\n const validation = FormatGoogleSheetTextSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const sheets = ctx.google.sheets({ version: 'v4', auth: ctx.authClient });\n\n // Get sheet information\n const rangeData = await sheets.spreadsheets.get({\n spreadsheetId: a.spreadsheetId,\n ranges: [a.range],\n fields: 'sheets(properties(sheetId,title))'\n });\n\n const { sheetName, cellRange: a1Range } = parseA1Range(a.range);\n const sheet = rangeData.data.sheets?.find(s => s.properties?.title === sheetName);\n if (!sheet || sheet.properties?.sheetId === undefined || sheet.properties?.sheetId === null) {\n return errorResponse(`Sheet \"${sheetName}\" not found`);\n }\n\n const gridRange = convertA1ToGridRange(a1Range, sheet.properties.sheetId!);\n\n const textFormat: any = {};\n const fields: string[] = [];\n\n if (a.bold !== undefined) {\n textFormat.bold = a.bold;\n fields.push('bold');\n }\n if (a.italic !== undefined) {\n textFormat.italic = a.italic;\n fields.push('italic');\n }\n if (a.strikethrough !== undefined) {\n textFormat.strikethrough = a.strikethrough;\n fields.push('strikethrough');\n }\n if (a.underline !== undefined) {\n textFormat.underline = a.underline;\n fields.push('underline');\n }\n if (a.fontSize !== undefined) {\n textFormat.fontSize = a.fontSize;\n fields.push('fontSize');\n }\n if (a.fontFamily !== undefined) {\n textFormat.fontFamily = a.fontFamily;\n fields.push('fontFamily');\n }\n if (a.foregroundColor) {\n textFormat.foregroundColor = {\n red: a.foregroundColor.red || 0,\n green: a.foregroundColor.green || 0,\n blue: a.foregroundColor.blue || 0\n };\n fields.push('foregroundColor');\n }\n\n const requests = [{\n repeatCell: {\n range: gridRange,\n cell: {\n userEnteredFormat: { textFormat }\n },\n fields: 'userEnteredFormat.textFormat(' + fields.join(',') + ')'\n }\n }];\n\n await sheets.spreadsheets.batchUpdate({\n spreadsheetId: a.spreadsheetId,\n requestBody: { requests }\n });\n\n return {\n content: [{ type: \"text\", text: `Applied text formatting to range ${a.range}` }],\n isError: false\n };\n }\n\n case \"formatGoogleSheetNumbers\": {\n const validation = FormatGoogleSheetNumbersSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const sheets = ctx.google.sheets({ version: 'v4', auth: ctx.authClient });\n\n const rangeData = await sheets.spreadsheets.get({\n spreadsheetId: a.spreadsheetId,\n ranges: [a.range],\n fields: 'sheets(properties(sheetId,title))'\n });\n\n const { sheetName, cellRange: a1Range } = parseA1Range(a.range);\n const sheet = rangeData.data.sheets?.find(s => s.properties?.title === sheetName);\n if (!sheet || sheet.properties?.sheetId === undefined || sheet.properties?.sheetId === null) {\n return errorResponse(`Sheet \"${sheetName}\" not found`);\n }\n\n const gridRange = convertA1ToGridRange(a1Range, sheet.properties.sheetId!);\n\n const numberFormat: any = {\n pattern: a.pattern\n };\n if (a.type) {\n numberFormat.type = a.type;\n }\n\n const requests = [{\n repeatCell: {\n range: gridRange,\n cell: {\n userEnteredFormat: { numberFormat }\n },\n fields: 'userEnteredFormat.numberFormat'\n }\n }];\n\n await sheets.spreadsheets.batchUpdate({\n spreadsheetId: a.spreadsheetId,\n requestBody: { requests }\n });\n\n return {\n content: [{ type: \"text\", text: `Applied number formatting to range ${a.range}` }],\n isError: false\n };\n }\n\n case \"setGoogleSheetBorders\": {\n const validation = SetGoogleSheetBordersSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const sheets = ctx.google.sheets({ version: 'v4', auth: ctx.authClient });\n\n const rangeData = await sheets.spreadsheets.get({\n spreadsheetId: a.spreadsheetId,\n ranges: [a.range],\n fields: 'sheets(properties(sheetId,title))'\n });\n\n const { sheetName, cellRange: a1Range } = parseA1Range(a.range);\n const sheet = rangeData.data.sheets?.find(s => s.properties?.title === sheetName);\n if (!sheet || sheet.properties?.sheetId === undefined || sheet.properties?.sheetId === null) {\n return errorResponse(`Sheet \"${sheetName}\" not found`);\n }\n\n const gridRange = convertA1ToGridRange(a1Range, sheet.properties.sheetId!);\n\n const border = {\n style: a.style,\n width: a.width || 1,\n color: a.color ? {\n red: a.color.red || 0,\n green: a.color.green || 0,\n blue: a.color.blue || 0\n } : undefined\n };\n\n const updateBordersRequest: any = {\n updateBorders: {\n range: gridRange\n }\n };\n\n if (a.top !== false) updateBordersRequest.updateBorders.top = border;\n if (a.bottom !== false) updateBordersRequest.updateBorders.bottom = border;\n if (a.left !== false) updateBordersRequest.updateBorders.left = border;\n if (a.right !== false) updateBordersRequest.updateBorders.right = border;\n if (a.innerHorizontal) updateBordersRequest.updateBorders.innerHorizontal = border;\n if (a.innerVertical) updateBordersRequest.updateBorders.innerVertical = border;\n\n await sheets.spreadsheets.batchUpdate({\n spreadsheetId: a.spreadsheetId,\n requestBody: { requests: [updateBordersRequest] }\n });\n\n return {\n content: [{ type: \"text\", text: `Set borders for range ${a.range}` }],\n isError: false\n };\n }\n\n case \"mergeGoogleSheetCells\": {\n const validation = MergeGoogleSheetCellsSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const sheets = ctx.google.sheets({ version: 'v4', auth: ctx.authClient });\n\n const rangeData = await sheets.spreadsheets.get({\n spreadsheetId: a.spreadsheetId,\n ranges: [a.range],\n fields: 'sheets(properties(sheetId,title))'\n });\n\n const { sheetName, cellRange: a1Range } = parseA1Range(a.range);\n const sheet = rangeData.data.sheets?.find(s => s.properties?.title === sheetName);\n if (!sheet || sheet.properties?.sheetId === undefined || sheet.properties?.sheetId === null) {\n return errorResponse(`Sheet \"${sheetName}\" not found`);\n }\n\n const gridRange = convertA1ToGridRange(a1Range, sheet.properties.sheetId!);\n\n const requests = [{\n mergeCells: {\n range: gridRange,\n mergeType: a.mergeType\n }\n }];\n\n await sheets.spreadsheets.batchUpdate({\n spreadsheetId: a.spreadsheetId,\n requestBody: { requests }\n });\n\n return {\n content: [{ type: \"text\", text: `Merged cells in range ${a.range} with type ${a.mergeType}` }],\n isError: false\n };\n }\n\n case \"addGoogleSheetConditionalFormat\": {\n const validation = AddGoogleSheetConditionalFormatSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const sheets = ctx.google.sheets({ version: 'v4', auth: ctx.authClient });\n\n const rangeData = await sheets.spreadsheets.get({\n spreadsheetId: a.spreadsheetId,\n ranges: [a.range],\n fields: 'sheets(properties(sheetId,title))'\n });\n\n const { sheetName, cellRange: a1Range } = parseA1Range(a.range);\n const sheet = rangeData.data.sheets?.find(s => s.properties?.title === sheetName);\n if (!sheet || sheet.properties?.sheetId === undefined || sheet.properties?.sheetId === null) {\n return errorResponse(`Sheet \"${sheetName}\" not found`);\n }\n\n const gridRange = convertA1ToGridRange(a1Range, sheet.properties.sheetId!);\n\n // Build condition based on type\n const booleanCondition: any = {};\n switch (a.condition.type) {\n case 'NUMBER_GREATER':\n booleanCondition.type = 'NUMBER_GREATER';\n booleanCondition.values = [{ userEnteredValue: a.condition.value }];\n break;\n case 'NUMBER_LESS':\n booleanCondition.type = 'NUMBER_LESS';\n booleanCondition.values = [{ userEnteredValue: a.condition.value }];\n break;\n case 'TEXT_CONTAINS':\n booleanCondition.type = 'TEXT_CONTAINS';\n booleanCondition.values = [{ userEnteredValue: a.condition.value }];\n break;\n case 'TEXT_STARTS_WITH':\n booleanCondition.type = 'TEXT_STARTS_WITH';\n booleanCondition.values = [{ userEnteredValue: a.condition.value }];\n break;\n case 'TEXT_ENDS_WITH':\n booleanCondition.type = 'TEXT_ENDS_WITH';\n booleanCondition.values = [{ userEnteredValue: a.condition.value }];\n break;\n case 'CUSTOM_FORMULA':\n booleanCondition.type = 'CUSTOM_FORMULA';\n booleanCondition.values = [{ userEnteredValue: a.condition.value }];\n break;\n }\n\n const format: any = {};\n if (a.format.backgroundColor) {\n format.backgroundColor = {\n red: a.format.backgroundColor.red || 0,\n green: a.format.backgroundColor.green || 0,\n blue: a.format.backgroundColor.blue || 0\n };\n }\n if (a.format.textFormat) {\n format.textFormat = {};\n if (a.format.textFormat.bold !== undefined) {\n format.textFormat.bold = a.format.textFormat.bold;\n }\n if (a.format.textFormat.foregroundColor) {\n format.textFormat.foregroundColor = {\n red: a.format.textFormat.foregroundColor.red || 0,\n green: a.format.textFormat.foregroundColor.green || 0,\n blue: a.format.textFormat.foregroundColor.blue || 0\n };\n }\n }\n\n const requests = [{\n addConditionalFormatRule: {\n rule: {\n ranges: [gridRange],\n booleanRule: {\n condition: booleanCondition,\n format: format\n }\n },\n index: 0\n }\n }];\n\n await sheets.spreadsheets.batchUpdate({\n spreadsheetId: a.spreadsheetId,\n requestBody: { requests }\n });\n\n return {\n content: [{ type: \"text\", text: `Added conditional formatting to range ${a.range}` }],\n isError: false\n };\n }\n\n case \"getSpreadsheetInfo\": {\n const validation = GetSpreadsheetInfoSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const sheets = ctx.google.sheets({ version: 'v4', auth: ctx.authClient });\n const response = await sheets.spreadsheets.get({\n spreadsheetId: a.spreadsheetId,\n fields: 'spreadsheetId,properties.title,sheets.properties'\n });\n\n const metadata = response.data;\n let result = `**Spreadsheet Information:**\\n\\n`;\n result += `**Title:** ${metadata.properties?.title || 'Untitled'}\\n`;\n result += `**ID:** ${metadata.spreadsheetId}\\n`;\n result += `**URL:** https://docs.google.com/spreadsheets/d/${metadata.spreadsheetId}\\n\\n`;\n\n const sheetList = metadata.sheets || [];\n result += `**Sheets (${sheetList.length}):**\\n`;\n for (let i = 0; i < sheetList.length; i++) {\n const props = sheetList[i].properties;\n result += `${i + 1}. **${props?.title || 'Untitled'}**\\n`;\n result += ` - Sheet ID: ${props?.sheetId}\\n`;\n result += ` - Grid: ${props?.gridProperties?.rowCount || 0} rows \u00D7 ${props?.gridProperties?.columnCount || 0} columns\\n`;\n if (props?.hidden) {\n result += ` - Status: Hidden\\n`;\n }\n result += `\\n`;\n }\n\n return {\n content: [{ type: \"text\", text: result }],\n isError: false\n };\n }\n\n case \"appendSpreadsheetRows\": {\n const validation = AppendSpreadsheetRowsSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const sheets = ctx.google.sheets({ version: 'v4', auth: ctx.authClient });\n const response = await sheets.spreadsheets.values.append({\n spreadsheetId: a.spreadsheetId,\n range: a.range,\n valueInputOption: a.valueInputOption || 'USER_ENTERED',\n insertDataOption: 'INSERT_ROWS',\n requestBody: { values: a.values }\n });\n\n const updatedCells = response.data.updates?.updatedCells || 0;\n const updatedRows = response.data.updates?.updatedRows || 0;\n const updatedRange = response.data.updates?.updatedRange || a.range;\n\n return {\n content: [{ type: \"text\", text: `Successfully appended ${updatedRows} row(s) (${updatedCells} cells) to spreadsheet. Updated range: ${updatedRange}` }],\n isError: false\n };\n }\n\n case \"addSpreadsheetSheet\":\n case \"addSheet\": {\n const isAlias = toolName === 'addSheet';\n const validation = isAlias ? AddSheetSchema.safeParse(args) : AddSpreadsheetSheetSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n\n const spreadsheetId = validation.data.spreadsheetId;\n const sheetTitle = isAlias ? (validation.data as z.infer<typeof AddSheetSchema>).title : (validation.data as z.infer<typeof AddSpreadsheetSheetSchema>).sheetTitle;\n\n const sheets = ctx.google.sheets({ version: 'v4', auth: ctx.authClient });\n const response = await sheets.spreadsheets.batchUpdate({\n spreadsheetId,\n requestBody: {\n requests: [{\n addSheet: {\n properties: {\n title: sheetTitle\n }\n }\n }]\n }\n });\n\n const addedSheet = response.data.replies?.[0]?.addSheet?.properties;\n if (!addedSheet) {\n return errorResponse('Failed to add sheet - no sheet properties returned.');\n }\n\n return {\n content: [{ type: \"text\", text: `Successfully added sheet \"${addedSheet.title}\" (Sheet ID: ${addedSheet.sheetId}) to spreadsheet.` }],\n isError: false\n };\n }\n\n case \"listSheets\": {\n const validation = ListSheetsSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const a = validation.data;\n\n const sheets = ctx.google.sheets({ version: 'v4', auth: ctx.authClient });\n const response = await sheets.spreadsheets.get({\n spreadsheetId: a.spreadsheetId,\n fields: 'sheets.properties(sheetId,title,index,hidden)'\n });\n\n const tabs = response.data.sheets || [];\n if (tabs.length === 0) {\n return { content: [{ type: 'text', text: 'No sheets found.' }], isError: false };\n }\n\n const lines = tabs.map((s) => `- ${s.properties?.title} (id: ${s.properties?.sheetId}, index: ${s.properties?.index}${s.properties?.hidden ? ', hidden' : ''})`);\n return { content: [{ type: 'text', text: `Sheets in spreadsheet ${a.spreadsheetId}:\\n${lines.join('\\n')}` }], isError: false };\n }\n\n case \"renameSheet\": {\n const validation = RenameSheetSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const a = validation.data;\n\n const sheets = ctx.google.sheets({ version: 'v4', auth: ctx.authClient });\n await sheets.spreadsheets.batchUpdate({\n spreadsheetId: a.spreadsheetId,\n requestBody: {\n requests: [{\n updateSheetProperties: {\n properties: { sheetId: a.sheetId, title: a.newTitle },\n fields: 'title'\n }\n }]\n }\n });\n\n return { content: [{ type: 'text', text: `Renamed sheet ${a.sheetId} to \"${a.newTitle}\".` }], isError: false };\n }\n\n case \"deleteSheet\": {\n const validation = DeleteSheetSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const a = validation.data;\n\n const sheets = ctx.google.sheets({ version: 'v4', auth: ctx.authClient });\n await sheets.spreadsheets.batchUpdate({\n spreadsheetId: a.spreadsheetId,\n requestBody: {\n requests: [{\n deleteSheet: { sheetId: a.sheetId }\n }]\n }\n });\n\n return { content: [{ type: 'text', text: `Deleted sheet ${a.sheetId}.` }], isError: false };\n }\n\n case \"addDataValidation\": {\n const validation = AddDataValidationSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const a = validation.data;\n\n const sheets = ctx.google.sheets({ version: 'v4', auth: ctx.authClient });\n const gridRange = await resolveGridRange(sheets, a.spreadsheetId, a.range);\n if (typeof gridRange === 'string') return errorResponse(gridRange);\n\n const conditionValues = a.values.map(v => ({ userEnteredValue: v }));\n\n await sheets.spreadsheets.batchUpdate({\n spreadsheetId: a.spreadsheetId,\n requestBody: {\n requests: [{\n setDataValidation: {\n range: gridRange,\n rule: {\n condition: {\n type: a.conditionType,\n values: conditionValues,\n },\n strict: a.strict,\n showCustomUi: a.showCustomUi,\n },\n },\n }],\n },\n });\n\n return { content: [{ type: 'text', text: `Added data validation (${a.conditionType}) to ${a.range}.` }], isError: false };\n }\n\n case \"protectRange\": {\n const validation = ProtectRangeSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const a = validation.data;\n\n const sheets = ctx.google.sheets({ version: 'v4', auth: ctx.authClient });\n const gridRange = await resolveGridRange(sheets, a.spreadsheetId, a.range);\n if (typeof gridRange === 'string') return errorResponse(gridRange);\n\n const response = await sheets.spreadsheets.batchUpdate({\n spreadsheetId: a.spreadsheetId,\n requestBody: {\n requests: [{\n addProtectedRange: {\n protectedRange: {\n range: gridRange,\n description: a.description,\n warningOnly: a.warningOnly,\n },\n },\n }],\n },\n });\n\n const protectedRangeId = response.data.replies?.[0]?.addProtectedRange?.protectedRange?.protectedRangeId;\n return { content: [{ type: 'text', text: `Protected range ${a.range}${protectedRangeId ? ` (id: ${protectedRangeId})` : ''}.` }], isError: false };\n }\n\n case \"addNamedRange\": {\n const validation = AddNamedRangeSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const a = validation.data;\n\n const sheets = ctx.google.sheets({ version: 'v4', auth: ctx.authClient });\n const gridRange = await resolveGridRange(sheets, a.spreadsheetId, a.range);\n if (typeof gridRange === 'string') return errorResponse(gridRange);\n\n const response = await sheets.spreadsheets.batchUpdate({\n spreadsheetId: a.spreadsheetId,\n requestBody: {\n requests: [{\n addNamedRange: {\n namedRange: {\n name: a.name,\n range: gridRange,\n },\n },\n }],\n },\n });\n\n const namedRangeId = response.data.replies?.[0]?.addNamedRange?.namedRange?.namedRangeId;\n return { content: [{ type: 'text', text: `Added named range \"${a.name}\" for ${a.range}${namedRangeId ? ` (id: ${namedRangeId})` : ''}.` }], isError: false };\n }\n\n case \"listGoogleSheets\": {\n const validation = ListGoogleSheetsSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n let queryString = \"mimeType='application/vnd.google-apps.spreadsheet' and trashed=false\";\n if (a.query) {\n const escapedQuery = escapeDriveQuery(a.query);\n queryString += ` and (name contains '${escapedQuery}' or fullText contains '${escapedQuery}')`;\n }\n\n const response = await ctx.getDrive().files.list({\n q: queryString,\n pageSize: a.maxResults || 20,\n orderBy: a.orderBy === 'name' ? 'name' : a.orderBy,\n fields: 'files(id,name,modifiedTime,createdTime,webViewLink,owners(displayName,emailAddress))',\n supportsAllDrives: true,\n includeItemsFromAllDrives: true\n });\n\n const files = response.data.files || [];\n if (files.length === 0) {\n return {\n content: [{ type: \"text\", text: \"No Google Spreadsheets found matching your criteria.\" }],\n isError: false\n };\n }\n\n let result = `Found ${files.length} Google Spreadsheet(s):\\n\\n`;\n for (let i = 0; i < files.length; i++) {\n const file = files[i];\n const modifiedDate = file.modifiedTime ? new Date(file.modifiedTime).toLocaleDateString() : 'Unknown';\n const owner = file.owners?.[0]?.displayName || 'Unknown';\n result += `${i + 1}. **${file.name}**\\n`;\n result += ` ID: ${file.id}\\n`;\n result += ` Modified: ${modifiedDate}\\n`;\n result += ` Owner: ${owner}\\n`;\n result += ` Link: ${file.webViewLink}\\n\\n`;\n }\n\n return {\n content: [{ type: \"text\", text: result }],\n isError: false\n };\n }\n\n default:\n return null;\n }\n}\n", "import { z } from 'zod';\nimport { v4 as uuidv4 } from 'uuid';\nimport type { slides_v1 } from 'googleapis';\nimport type { ToolDefinition, ToolResult, ToolContext } from '../types.js';\nimport { errorResponse } from '../types.js';\nimport { uploadImageToDrive, deleteDriveFile } from '../utils/driveImageUpload.js';\n\n// ---------------------------------------------------------------------------\n// Zod Schemas\n// ---------------------------------------------------------------------------\n\nconst CreateGoogleSlidesSchema = z.object({\n name: z.string().min(1, \"Presentation name is required\"),\n slides: z.array(z.object({\n title: z.string(),\n content: z.string()\n })).min(1, \"At least one slide is required\"),\n parentFolderId: z.string().optional()\n});\n\nconst UpdateGoogleSlidesSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n slides: z.array(z.object({\n title: z.string(),\n content: z.string()\n })).min(1, \"At least one slide is required\")\n});\n\nconst GetGoogleSlidesContentSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n slideIndex: z.number().min(0).optional()\n});\n\nconst FormatGoogleSlidesTextSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n objectId: z.string().min(1, \"Object ID is required\"),\n startIndex: z.number().min(0).optional(),\n endIndex: z.number().min(0).optional(),\n bold: z.boolean().optional(),\n italic: z.boolean().optional(),\n underline: z.boolean().optional(),\n strikethrough: z.boolean().optional(),\n fontSize: z.number().optional(),\n fontFamily: z.string().optional(),\n foregroundColor: z.object({\n red: z.number().min(0).max(1).optional(),\n green: z.number().min(0).max(1).optional(),\n blue: z.number().min(0).max(1).optional()\n }).optional()\n});\n\nconst FormatGoogleSlidesParagraphSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n objectId: z.string().min(1, \"Object ID is required\"),\n alignment: z.enum(['START', 'CENTER', 'END', 'JUSTIFIED']).optional(),\n lineSpacing: z.number().optional(),\n bulletStyle: z.enum(['NONE', 'DISC', 'ARROW', 'SQUARE', 'DIAMOND', 'STAR', 'NUMBERED']).optional()\n});\n\nconst StyleGoogleSlidesShapeSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n objectId: z.string().min(1, \"Shape object ID is required\"),\n backgroundColor: z.object({\n red: z.number().min(0).max(1).optional(),\n green: z.number().min(0).max(1).optional(),\n blue: z.number().min(0).max(1).optional(),\n alpha: z.number().min(0).max(1).optional()\n }).optional(),\n outlineColor: z.object({\n red: z.number().min(0).max(1).optional(),\n green: z.number().min(0).max(1).optional(),\n blue: z.number().min(0).max(1).optional()\n }).optional(),\n outlineWeight: z.number().optional(),\n outlineDashStyle: z.enum(['SOLID', 'DOT', 'DASH', 'DASH_DOT', 'LONG_DASH', 'LONG_DASH_DOT']).optional()\n});\n\nconst SetGoogleSlidesBackgroundSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n pageObjectIds: z.array(z.string()).min(1, \"At least one page object ID is required\"),\n backgroundColor: z.object({\n red: z.number().min(0).max(1).optional(),\n green: z.number().min(0).max(1).optional(),\n blue: z.number().min(0).max(1).optional(),\n alpha: z.number().min(0).max(1).optional()\n })\n});\n\nconst CreateGoogleSlidesTextBoxSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n pageObjectId: z.string().min(1, \"Page object ID is required\"),\n text: z.string().min(1, \"Text content is required\"),\n x: z.number(),\n y: z.number(),\n width: z.number(),\n height: z.number(),\n fontSize: z.number().optional(),\n bold: z.boolean().optional(),\n italic: z.boolean().optional()\n});\n\nconst CreateGoogleSlidesShapeSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n pageObjectId: z.string().min(1, \"Page object ID is required\"),\n shapeType: z.enum(['RECTANGLE', 'ELLIPSE', 'DIAMOND', 'TRIANGLE', 'STAR', 'ROUND_RECTANGLE', 'ARROW']),\n x: z.number(),\n y: z.number(),\n width: z.number(),\n height: z.number(),\n backgroundColor: z.object({\n red: z.number().min(0).max(1).optional(),\n green: z.number().min(0).max(1).optional(),\n blue: z.number().min(0).max(1).optional(),\n alpha: z.number().min(0).max(1).optional()\n }).optional()\n});\n\nconst GetGoogleSlidesSpeakerNotesSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n slideIndex: z.number().min(0, \"Slide index must be non-negative\")\n});\n\nconst UpdateGoogleSlidesSpeakerNotesSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n slideIndex: z.number().min(0, \"Slide index must be non-negative\"),\n notes: z.string()\n});\n\nconst DeleteGoogleSlideSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n slideObjectId: z.string().min(1, \"Slide object ID is required\")\n});\n\nconst DuplicateSlideSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n slideObjectId: z.string().min(1, \"Slide object ID is required\")\n});\n\nconst ReorderSlidesSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n slideObjectIds: z.array(z.string().min(1)).min(1, \"At least one slide object ID is required\"),\n insertionIndex: z.number().int().min(0)\n});\n\nconst ReplaceAllTextInSlidesSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n containsText: z.string().min(1, \"containsText is required\"),\n replaceText: z.string(),\n matchCase: z.boolean().optional().default(false)\n});\n\nconst ExportSlideThumbnailSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n slideObjectId: z.string().min(1, \"Slide object ID is required\"),\n mimeType: z.enum([\"PNG\", \"JPEG\"]).optional().default(\"PNG\"),\n size: z.enum([\"SMALL\", \"MEDIUM\", \"LARGE\"]).optional().default(\"LARGE\")\n});\n\nconst InsertSlidesImageFromUrlSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n pageObjectId: z.string().min(1, \"Slide/page object ID is required\"),\n imageUrl: z.string().url(\"A valid image URL is required\"),\n x: z.number().optional().default(0),\n y: z.number().optional().default(0),\n width: z.number().optional(),\n height: z.number().optional(),\n});\n\nconst MoveSlideElementSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n objectId: z.string().min(1, \"Element object ID is required\"),\n x: z.number().optional(),\n y: z.number().optional(),\n width: z.number().optional(),\n height: z.number().optional(),\n});\n\nconst DeleteSlideElementSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n objectId: z.string().min(1, \"Element object ID is required\"),\n});\n\nconst GetSlideElementInfoSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n slideObjectId: z.string().optional(),\n});\n\nconst InsertSlidesLocalImageSchema = z.object({\n presentationId: z.string().min(1, \"Presentation ID is required\"),\n pageObjectId: z.string().min(1, \"Slide/page object ID is required\"),\n localImagePath: z.string().min(1, \"Local image path is required\"),\n x: z.number().optional().default(0),\n y: z.number().optional().default(0),\n width: z.number().optional(),\n height: z.number().optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nasync function insertImageIntoSlide(\n ctx: ToolContext,\n presentationId: string,\n pageObjectId: string,\n imageUrl: string,\n x: number,\n y: number,\n width?: number,\n height?: number,\n): Promise<ToolResult> {\n const slidesService = ctx.google.slides({ version: 'v1', auth: ctx.authClient });\n const objectId = `img_${uuidv4().substring(0, 8)}`;\n\n const elementProperties: slides_v1.Schema$PageElementProperties = {\n pageObjectId,\n transform: {\n scaleX: 1,\n scaleY: 1,\n translateX: x,\n translateY: y,\n unit: 'EMU',\n },\n };\n\n if (width != null && height != null) {\n elementProperties.size = {\n width: { magnitude: width, unit: 'EMU' },\n height: { magnitude: height, unit: 'EMU' },\n };\n }\n\n await slidesService.presentations.batchUpdate({\n presentationId,\n requestBody: {\n requests: [{\n createImage: { objectId, url: imageUrl, elementProperties },\n }],\n },\n });\n\n return {\n content: [{ type: 'text', text: `Inserted image into slide ${pageObjectId} (objectId: ${objectId})` }],\n isError: false,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Tool Definitions\n// ---------------------------------------------------------------------------\n\nexport const toolDefinitions: ToolDefinition[] = [\n {\n name: \"createGoogleSlides\",\n description: \"Create a new Google Slides presentation\",\n inputSchema: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"Presentation name\" },\n slides: {\n type: \"array\",\n description: \"Array of slide objects\",\n items: {\n type: \"object\",\n properties: {\n title: { type: \"string\" },\n content: { type: \"string\" }\n }\n }\n },\n parentFolderId: { type: \"string\", description: \"Parent folder ID (defaults to root)\" }\n },\n required: [\"name\", \"slides\"]\n }\n },\n {\n name: \"updateGoogleSlides\",\n description: \"Update an existing Google Slides presentation\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n slides: {\n type: \"array\",\n description: \"Array of slide objects to replace existing slides\",\n items: {\n type: \"object\",\n properties: {\n title: { type: \"string\" },\n content: { type: \"string\" }\n }\n }\n }\n },\n required: [\"presentationId\", \"slides\"]\n }\n },\n {\n name: \"getGoogleSlidesContent\",\n description: \"Get content of Google Slides with element IDs for formatting\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n slideIndex: { type: \"number\", description: \"Specific slide index (optional)\" }\n },\n required: [\"presentationId\"]\n }\n },\n {\n name: \"formatGoogleSlidesText\",\n description: \"Apply text formatting to elements in Google Slides\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n objectId: { type: \"string\", description: \"Object ID of the text element\" },\n startIndex: { type: \"number\", description: \"Start index (0-based)\" },\n endIndex: { type: \"number\", description: \"End index (0-based)\" },\n bold: { type: \"boolean\", description: \"Make text bold\" },\n italic: { type: \"boolean\", description: \"Make text italic\" },\n underline: { type: \"boolean\", description: \"Underline text\" },\n strikethrough: { type: \"boolean\", description: \"Strikethrough text\" },\n fontSize: { type: \"number\", description: \"Font size in points\" },\n fontFamily: { type: \"string\", description: \"Font family name\" },\n foregroundColor: {\n type: \"object\",\n description: \"Text color (RGB values 0-1)\",\n properties: {\n red: { type: \"number\" },\n green: { type: \"number\" },\n blue: { type: \"number\" }\n }\n }\n },\n required: [\"presentationId\", \"objectId\"]\n }\n },\n {\n name: \"formatGoogleSlidesParagraph\",\n description: \"Apply paragraph formatting to text in Google Slides\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n objectId: { type: \"string\", description: \"Object ID of the text element\" },\n alignment: {\n type: \"string\",\n description: \"Text alignment\",\n enum: [\"START\", \"CENTER\", \"END\", \"JUSTIFIED\"]\n },\n lineSpacing: { type: \"number\", description: \"Line spacing multiplier\" },\n bulletStyle: {\n type: \"string\",\n description: \"Bullet style\",\n enum: [\"NONE\", \"DISC\", \"ARROW\", \"SQUARE\", \"DIAMOND\", \"STAR\", \"NUMBERED\"]\n }\n },\n required: [\"presentationId\", \"objectId\"]\n }\n },\n {\n name: \"styleGoogleSlidesShape\",\n description: \"Style shapes in Google Slides\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n objectId: { type: \"string\", description: \"Shape object ID\" },\n backgroundColor: {\n type: \"object\",\n description: \"Background color (RGBA values 0-1)\",\n properties: {\n red: { type: \"number\" },\n green: { type: \"number\" },\n blue: { type: \"number\" },\n alpha: { type: \"number\" }\n }\n },\n outlineColor: {\n type: \"object\",\n description: \"Outline color (RGB values 0-1)\",\n properties: {\n red: { type: \"number\" },\n green: { type: \"number\" },\n blue: { type: \"number\" }\n }\n },\n outlineWeight: { type: \"number\", description: \"Outline thickness in points\" },\n outlineDashStyle: {\n type: \"string\",\n description: \"Outline dash style\",\n enum: [\"SOLID\", \"DOT\", \"DASH\", \"DASH_DOT\", \"LONG_DASH\", \"LONG_DASH_DOT\"]\n }\n },\n required: [\"presentationId\", \"objectId\"]\n }\n },\n {\n name: \"setGoogleSlidesBackground\",\n description: \"Set background color for slides\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n pageObjectIds: {\n type: \"array\",\n description: \"Array of slide IDs to update\",\n items: { type: \"string\" }\n },\n backgroundColor: {\n type: \"object\",\n description: \"Background color (RGBA values 0-1)\",\n properties: {\n red: { type: \"number\" },\n green: { type: \"number\" },\n blue: { type: \"number\" },\n alpha: { type: \"number\" }\n }\n }\n },\n required: [\"presentationId\", \"pageObjectIds\", \"backgroundColor\"]\n }\n },\n {\n name: \"createGoogleSlidesTextBox\",\n description: \"Create a text box in Google Slides\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n pageObjectId: { type: \"string\", description: \"Slide ID\" },\n text: { type: \"string\", description: \"Text content\" },\n x: { type: \"number\", description: \"X position in EMU (1/360000 cm)\" },\n y: { type: \"number\", description: \"Y position in EMU\" },\n width: { type: \"number\", description: \"Width in EMU\" },\n height: { type: \"number\", description: \"Height in EMU\" },\n fontSize: { type: \"number\", description: \"Font size in points\" },\n bold: { type: \"boolean\", description: \"Make text bold\" },\n italic: { type: \"boolean\", description: \"Make text italic\" }\n },\n required: [\"presentationId\", \"pageObjectId\", \"text\", \"x\", \"y\", \"width\", \"height\"]\n }\n },\n {\n name: \"createGoogleSlidesShape\",\n description: \"Create a shape in Google Slides\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n pageObjectId: { type: \"string\", description: \"Slide ID\" },\n shapeType: {\n type: \"string\",\n description: \"Shape type\",\n enum: [\"RECTANGLE\", \"ELLIPSE\", \"DIAMOND\", \"TRIANGLE\", \"STAR\", \"ROUND_RECTANGLE\", \"ARROW\"]\n },\n x: { type: \"number\", description: \"X position in EMU\" },\n y: { type: \"number\", description: \"Y position in EMU\" },\n width: { type: \"number\", description: \"Width in EMU\" },\n height: { type: \"number\", description: \"Height in EMU\" },\n backgroundColor: {\n type: \"object\",\n description: \"Fill color (RGBA values 0-1)\",\n properties: {\n red: { type: \"number\" },\n green: { type: \"number\" },\n blue: { type: \"number\" },\n alpha: { type: \"number\" }\n }\n }\n },\n required: [\"presentationId\", \"pageObjectId\", \"shapeType\", \"x\", \"y\", \"width\", \"height\"]\n }\n },\n {\n name: \"getGoogleSlidesSpeakerNotes\",\n description: \"Get speaker notes from a specific slide in Google Slides\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n slideIndex: { type: \"number\", description: \"Slide index (0-based)\" }\n },\n required: [\"presentationId\", \"slideIndex\"]\n }\n },\n {\n name: \"updateGoogleSlidesSpeakerNotes\",\n description: \"Update speaker notes for a specific slide in Google Slides\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n slideIndex: { type: \"number\", description: \"Slide index (0-based)\" },\n notes: { type: \"string\", description: \"Speaker notes content\" }\n },\n required: [\"presentationId\", \"slideIndex\", \"notes\"]\n }\n },\n {\n name: \"deleteGoogleSlide\",\n description: \"Delete a slide from a presentation\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n slideObjectId: { type: \"string\", description: \"Slide object ID\" }\n },\n required: [\"presentationId\", \"slideObjectId\"]\n }\n },\n {\n name: \"duplicateSlide\",\n description: \"Duplicate a slide in a presentation\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n slideObjectId: { type: \"string\", description: \"Slide object ID\" }\n },\n required: [\"presentationId\", \"slideObjectId\"]\n }\n },\n {\n name: \"reorderSlides\",\n description: \"Reorder one or more slides in a presentation\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n slideObjectIds: { type: \"array\", items: { type: \"string\" }, description: \"Slide object IDs to move\" },\n insertionIndex: { type: \"number\", description: \"Target insertion index\" }\n },\n required: [\"presentationId\", \"slideObjectIds\", \"insertionIndex\"]\n }\n },\n {\n name: \"replaceAllTextInSlides\",\n description: \"Replace all matching text across presentation slides\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n containsText: { type: \"string\", description: \"Text to find\" },\n replaceText: { type: \"string\", description: \"Replacement text\" },\n matchCase: { type: \"boolean\", description: \"Case-sensitive match\" }\n },\n required: [\"presentationId\", \"containsText\", \"replaceText\"]\n }\n },\n {\n name: \"exportSlideThumbnail\",\n description: \"Export a slide thumbnail URL\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n slideObjectId: { type: \"string\", description: \"Slide object ID\" },\n mimeType: { type: \"string\", enum: [\"PNG\", \"JPEG\"], description: \"Thumbnail MIME type\" },\n size: { type: \"string\", enum: [\"SMALL\", \"MEDIUM\", \"LARGE\"], description: \"Thumbnail size\" }\n },\n required: [\"presentationId\", \"slideObjectId\"]\n }\n },\n {\n name: \"insertSlidesImageFromUrl\",\n description: \"Insert an image into a Google Slides slide from a publicly accessible URL\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n pageObjectId: { type: \"string\", description: \"Slide/page object ID to insert the image into\" },\n imageUrl: { type: \"string\", description: \"Publicly accessible URL of the image\" },\n x: { type: \"number\", description: \"X position in EMU (default: 0)\" },\n y: { type: \"number\", description: \"Y position in EMU (default: 0)\" },\n width: { type: \"number\", description: \"Width in EMU (omit to auto-size)\" },\n height: { type: \"number\", description: \"Height in EMU (omit to auto-size)\" }\n },\n required: [\"presentationId\", \"pageObjectId\", \"imageUrl\"]\n }\n },\n {\n name: \"getSlideElementInfo\",\n description: \"Get position, size, and transform of all elements on a slide. Returns actual rendered bounds.\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n slideObjectId: { type: \"string\", description: \"Slide object ID (omit to get all slides)\" }\n },\n required: [\"presentationId\"]\n }\n },\n {\n name: \"moveSlideElement\",\n description: \"Move and/or resize an element (image, text box, shape) on a Google Slides slide\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n objectId: { type: \"string\", description: \"Element object ID to move/resize\" },\n x: { type: \"number\", description: \"New X position in EMU\" },\n y: { type: \"number\", description: \"New Y position in EMU\" },\n width: { type: \"number\", description: \"New width in EMU\" },\n height: { type: \"number\", description: \"New height in EMU\" }\n },\n required: [\"presentationId\", \"objectId\"]\n }\n },\n {\n name: \"deleteSlideElement\",\n description: \"Delete an element (image, text box, shape) from a Google Slides slide\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n objectId: { type: \"string\", description: \"Element object ID to delete\" }\n },\n required: [\"presentationId\", \"objectId\"]\n }\n },\n {\n name: \"insertSlidesLocalImage\",\n description: \"Upload a local image file to Google Drive and insert it into a Google Slides slide\",\n inputSchema: {\n type: \"object\",\n properties: {\n presentationId: { type: \"string\", description: \"Presentation ID\" },\n pageObjectId: { type: \"string\", description: \"Slide/page object ID to insert the image into\" },\n localImagePath: { type: \"string\", description: \"Absolute path to the local image file\" },\n x: { type: \"number\", description: \"X position in EMU (default: 0)\" },\n y: { type: \"number\", description: \"Y position in EMU (default: 0)\" },\n width: { type: \"number\", description: \"Width in EMU (omit to auto-size)\" },\n height: { type: \"number\", description: \"Height in EMU (omit to auto-size)\" }\n },\n required: [\"presentationId\", \"pageObjectId\", \"localImagePath\"]\n }\n },\n];\n\n// ---------------------------------------------------------------------------\n// Handler\n// ---------------------------------------------------------------------------\n\nexport async function handleTool(\n toolName: string,\n args: Record<string, unknown>,\n ctx: ToolContext\n): Promise<ToolResult | null> {\n switch (toolName) {\n\n case \"createGoogleSlides\": {\n const validation = CreateGoogleSlidesSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const parentFolderId = await ctx.resolveFolderId(a.parentFolderId);\n\n // Check if presentation already exists\n const existingFileId = await ctx.checkFileExists(a.name, parentFolderId);\n if (existingFileId) {\n return errorResponse(\n `A presentation named \"${a.name}\" already exists in this location. ` +\n `File ID: ${existingFileId}. To modify it, you can use Google Slides directly.`\n );\n }\n\n const slidesService = ctx.google.slides({ version: 'v1', auth: ctx.authClient });\n const presentation = await slidesService.presentations.create({\n requestBody: { title: a.name },\n });\n\n await ctx.getDrive().files.update({\n fileId: presentation.data.presentationId!,\n addParents: parentFolderId,\n removeParents: 'root',\n supportsAllDrives: true\n });\n\n for (const slide of a.slides) {\n const slideObjectId = `slide_${uuidv4().substring(0, 8)}`;\n await slidesService.presentations.batchUpdate({\n presentationId: presentation.data.presentationId!,\n requestBody: {\n requests: [{\n createSlide: {\n objectId: slideObjectId,\n slideLayoutReference: { predefinedLayout: 'TITLE_AND_BODY' },\n }\n }]\n },\n });\n\n const slidePage = await slidesService.presentations.pages.get({\n presentationId: presentation.data.presentationId!,\n pageObjectId: slideObjectId,\n });\n\n let titlePlaceholderId = '';\n let bodyPlaceholderId = '';\n slidePage.data.pageElements?.forEach((el) => {\n if (el.shape?.placeholder?.type === 'TITLE') {\n titlePlaceholderId = el.objectId!;\n } else if (el.shape?.placeholder?.type === 'BODY') {\n bodyPlaceholderId = el.objectId!;\n }\n });\n\n await slidesService.presentations.batchUpdate({\n presentationId: presentation.data.presentationId!,\n requestBody: {\n requests: [\n { insertText: { objectId: titlePlaceholderId, text: slide.title, insertionIndex: 0 } },\n { insertText: { objectId: bodyPlaceholderId, text: slide.content, insertionIndex: 0 } }\n ]\n },\n });\n }\n\n return {\n content: [{\n type: 'text',\n text: `Created Google Slides presentation: ${a.name}\\nID: ${presentation.data.presentationId}\\nLink: https://docs.google.com/presentation/d/${presentation.data.presentationId}`,\n }],\n isError: false,\n };\n }\n\n case \"updateGoogleSlides\": {\n const validation = UpdateGoogleSlidesSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const slidesService = ctx.google.slides({ version: 'v1', auth: ctx.authClient });\n\n // Get current presentation details\n const currentPresentation = await slidesService.presentations.get({\n presentationId: a.presentationId\n });\n\n if (!currentPresentation.data.slides) {\n return errorResponse(\"No slides found in presentation\");\n }\n\n // Collect all slide IDs except the first one (we'll keep it for now)\n const slideIdsToDelete = currentPresentation.data.slides\n .slice(1)\n .map(slide => slide.objectId)\n .filter((id): id is string => id !== undefined);\n\n // Prepare requests to update presentation\n const requests: any[] = [];\n\n // Delete all slides except the first one\n if (slideIdsToDelete.length > 0) {\n slideIdsToDelete.forEach(slideId => {\n requests.push({\n deleteObject: { objectId: slideId }\n });\n });\n }\n\n // Now we need to update the first slide or create new slides\n if (a.slides.length === 0) {\n return errorResponse(\"At least one slide must be provided\");\n }\n\n // Clear content of the first slide\n const firstSlide = currentPresentation.data.slides[0];\n if (firstSlide && firstSlide.pageElements) {\n // Find text elements to clear\n firstSlide.pageElements.forEach(element => {\n if (element.objectId && element.shape?.text) {\n requests.push({\n deleteText: {\n objectId: element.objectId,\n textRange: { type: 'ALL' }\n }\n });\n }\n });\n }\n\n // Update the first slide with new content\n const firstSlideContent = a.slides[0];\n if (firstSlide && firstSlide.pageElements) {\n // Find title and body placeholders\n let titlePlaceholderId: string | undefined;\n let bodyPlaceholderId: string | undefined;\n\n firstSlide.pageElements.forEach(element => {\n if (element.shape?.placeholder?.type === 'TITLE' || element.shape?.placeholder?.type === 'CENTERED_TITLE') {\n titlePlaceholderId = element.objectId || undefined;\n } else if (element.shape?.placeholder?.type === 'BODY' || element.shape?.placeholder?.type === 'SUBTITLE') {\n bodyPlaceholderId = element.objectId || undefined;\n }\n });\n\n if (titlePlaceholderId) {\n requests.push({\n insertText: {\n objectId: titlePlaceholderId,\n text: firstSlideContent.title,\n insertionIndex: 0\n }\n });\n }\n\n if (bodyPlaceholderId) {\n requests.push({\n insertText: {\n objectId: bodyPlaceholderId,\n text: firstSlideContent.content,\n insertionIndex: 0\n }\n });\n }\n }\n\n // Add any additional slides from the request\n for (let i = 1; i < a.slides.length; i++) {\n const slideId = `slide_${Date.now()}_${i}`;\n\n requests.push({\n createSlide: {\n objectId: slideId,\n slideLayoutReference: {\n predefinedLayout: 'TITLE_AND_BODY'\n }\n }\n });\n\n // We'll need to add content to these slides in a separate batch update\n // because we need to wait for the slides to be created first\n }\n\n // Execute the batch update\n await slidesService.presentations.batchUpdate({\n presentationId: a.presentationId,\n requestBody: { requests }\n });\n\n // If we have additional slides, add their content\n if (a.slides.length > 1) {\n const contentRequests: any[] = [];\n\n // Get updated presentation to find the new slide IDs\n const updatedPresentation = await slidesService.presentations.get({\n presentationId: a.presentationId\n });\n\n // Add content to the new slides (starting from the second slide in our args)\n for (let i = 1; i < a.slides.length && updatedPresentation.data.slides; i++) {\n const slide = a.slides[i];\n const presentationSlide = updatedPresentation.data.slides[i];\n\n if (presentationSlide && presentationSlide.pageElements) {\n presentationSlide.pageElements.forEach(element => {\n if (element.objectId) {\n if (element.shape?.placeholder?.type === 'TITLE' || element.shape?.placeholder?.type === 'CENTERED_TITLE') {\n contentRequests.push({\n insertText: {\n objectId: element.objectId,\n text: slide.title,\n insertionIndex: 0\n }\n });\n } else if (element.shape?.placeholder?.type === 'BODY' || element.shape?.placeholder?.type === 'SUBTITLE') {\n contentRequests.push({\n insertText: {\n objectId: element.objectId,\n text: slide.content,\n insertionIndex: 0\n }\n });\n }\n }\n });\n }\n }\n\n if (contentRequests.length > 0) {\n await slidesService.presentations.batchUpdate({\n presentationId: a.presentationId,\n requestBody: { requests: contentRequests }\n });\n }\n }\n\n return {\n content: [{\n type: 'text',\n text: `Updated Google Slides presentation with ${a.slides.length} slide(s)\\nLink: https://docs.google.com/presentation/d/${a.presentationId}`,\n }],\n isError: false,\n };\n }\n\n case \"getGoogleSlidesContent\": {\n const validation = GetGoogleSlidesContentSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const slidesService = ctx.google.slides({ version: 'v1', auth: ctx.authClient });\n const presentation = await slidesService.presentations.get({\n presentationId: a.presentationId\n });\n\n if (!presentation.data.slides) {\n return errorResponse(\"No slides found in presentation\");\n }\n\n let content = 'Presentation content with element IDs:\\n\\n';\n const slides = a.slideIndex !== undefined\n ? [presentation.data.slides[a.slideIndex]]\n : presentation.data.slides;\n\n slides.forEach((slide, index) => {\n if (!slide || !slide.objectId) return;\n\n content += `\\nSlide ${a.slideIndex ?? index} (ID: ${slide.objectId}):\\n`;\n content += '----------------------------\\n';\n\n if (slide.pageElements) {\n slide.pageElements.forEach((element) => {\n if (!element.objectId) return;\n\n if (element.shape?.text) {\n content += ` Text Box (ID: ${element.objectId}):\\n`;\n const textElements = element.shape.text.textElements || [];\n let text = '';\n textElements.forEach((textElement) => {\n if (textElement.textRun?.content) {\n text += textElement.textRun.content;\n }\n });\n content += ` \"${text.trim()}\"\\n`;\n } else if (element.shape) {\n content += ` Shape (ID: ${element.objectId}): ${element.shape.shapeType || 'Unknown'}\\n`;\n } else if (element.image) {\n content += ` Image (ID: ${element.objectId})\\n`;\n } else if (element.video) {\n content += ` Video (ID: ${element.objectId})\\n`;\n } else if (element.table) {\n content += ` Table (ID: ${element.objectId})\\n`;\n }\n });\n }\n });\n\n return {\n content: [{ type: \"text\", text: content }],\n isError: false\n };\n }\n\n case \"formatGoogleSlidesText\": {\n const validation = FormatGoogleSlidesTextSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const slidesService = ctx.google.slides({ version: 'v1', auth: ctx.authClient });\n const textStyle: any = {};\n const fields: string[] = [];\n\n if (a.bold !== undefined) {\n textStyle.bold = a.bold;\n fields.push('bold');\n }\n\n if (a.italic !== undefined) {\n textStyle.italic = a.italic;\n fields.push('italic');\n }\n\n if (a.underline !== undefined) {\n textStyle.underline = a.underline;\n fields.push('underline');\n }\n\n if (a.strikethrough !== undefined) {\n textStyle.strikethrough = a.strikethrough;\n fields.push('strikethrough');\n }\n\n if (a.fontSize !== undefined) {\n textStyle.fontSize = {\n magnitude: a.fontSize,\n unit: 'PT'\n };\n fields.push('fontSize');\n }\n\n if (a.fontFamily !== undefined) {\n textStyle.fontFamily = a.fontFamily;\n fields.push('fontFamily');\n }\n\n if (a.foregroundColor) {\n textStyle.foregroundColor = {\n opaqueColor: {\n rgbColor: {\n red: a.foregroundColor.red || 0,\n green: a.foregroundColor.green || 0,\n blue: a.foregroundColor.blue || 0\n }\n }\n };\n fields.push('foregroundColor');\n }\n\n if (fields.length === 0) {\n return errorResponse(\"No formatting options specified\");\n }\n\n const updateRequest: any = {\n updateTextStyle: {\n objectId: a.objectId,\n style: textStyle,\n fields: fields.join(',')\n }\n };\n\n // Add text range if specified\n if (a.startIndex !== undefined && a.endIndex !== undefined) {\n updateRequest.updateTextStyle.textRange = {\n type: 'FIXED_RANGE',\n startIndex: a.startIndex,\n endIndex: a.endIndex\n };\n } else {\n updateRequest.updateTextStyle.textRange = { type: 'ALL' };\n }\n\n await slidesService.presentations.batchUpdate({\n presentationId: a.presentationId,\n requestBody: { requests: [updateRequest] }\n });\n\n return {\n content: [{ type: \"text\", text: `Applied text formatting to object ${a.objectId}` }],\n isError: false\n };\n }\n\n case \"formatGoogleSlidesParagraph\": {\n const validation = FormatGoogleSlidesParagraphSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const slidesService = ctx.google.slides({ version: 'v1', auth: ctx.authClient });\n const requests: any[] = [];\n\n if (a.alignment) {\n requests.push({\n updateParagraphStyle: {\n objectId: a.objectId,\n style: { alignment: a.alignment },\n fields: 'alignment'\n }\n });\n }\n\n if (a.lineSpacing !== undefined) {\n requests.push({\n updateParagraphStyle: {\n objectId: a.objectId,\n style: { lineSpacing: a.lineSpacing },\n fields: 'lineSpacing'\n }\n });\n }\n\n if (a.bulletStyle) {\n if (a.bulletStyle === 'NONE') {\n requests.push({\n deleteParagraphBullets: {\n objectId: a.objectId\n }\n });\n } else if (a.bulletStyle === 'NUMBERED') {\n requests.push({\n createParagraphBullets: {\n objectId: a.objectId,\n bulletPreset: 'NUMBERED_DIGIT_ALPHA_ROMAN'\n }\n });\n } else {\n requests.push({\n createParagraphBullets: {\n objectId: a.objectId,\n bulletPreset: `BULLET_${a.bulletStyle}_CIRCLE_SQUARE`\n }\n });\n }\n }\n\n if (requests.length === 0) {\n return errorResponse(\"No formatting options specified\");\n }\n\n await slidesService.presentations.batchUpdate({\n presentationId: a.presentationId,\n requestBody: { requests }\n });\n\n return {\n content: [{ type: \"text\", text: `Applied paragraph formatting to object ${a.objectId}` }],\n isError: false\n };\n }\n\n case \"styleGoogleSlidesShape\": {\n const validation = StyleGoogleSlidesShapeSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const slidesService = ctx.google.slides({ version: 'v1', auth: ctx.authClient });\n const shapeProperties: any = {};\n const fields: string[] = [];\n\n if (a.backgroundColor) {\n shapeProperties.shapeBackgroundFill = {\n solidFill: {\n color: {\n rgbColor: {\n red: a.backgroundColor.red || 0,\n green: a.backgroundColor.green || 0,\n blue: a.backgroundColor.blue || 0\n }\n },\n alpha: a.backgroundColor.alpha || 1\n }\n };\n fields.push('shapeBackgroundFill');\n }\n\n const outline: any = {};\n let hasOutlineChanges = false;\n\n if (a.outlineColor) {\n outline.outlineFill = {\n solidFill: {\n color: {\n rgbColor: {\n red: a.outlineColor.red || 0,\n green: a.outlineColor.green || 0,\n blue: a.outlineColor.blue || 0\n }\n }\n }\n };\n hasOutlineChanges = true;\n }\n\n if (a.outlineWeight !== undefined) {\n outline.weight = {\n magnitude: a.outlineWeight,\n unit: 'PT'\n };\n hasOutlineChanges = true;\n }\n\n if (a.outlineDashStyle !== undefined) {\n outline.dashStyle = a.outlineDashStyle;\n hasOutlineChanges = true;\n }\n\n if (hasOutlineChanges) {\n shapeProperties.outline = outline;\n fields.push('outline');\n }\n\n if (fields.length === 0) {\n return errorResponse(\"No styling options specified\");\n }\n\n await slidesService.presentations.batchUpdate({\n presentationId: a.presentationId,\n requestBody: {\n requests: [{\n updateShapeProperties: {\n objectId: a.objectId,\n shapeProperties,\n fields: fields.join(',')\n }\n }]\n }\n });\n\n return {\n content: [{ type: \"text\", text: `Applied styling to shape ${a.objectId}` }],\n isError: false\n };\n }\n\n case \"setGoogleSlidesBackground\": {\n const validation = SetGoogleSlidesBackgroundSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const slidesService = ctx.google.slides({ version: 'v1', auth: ctx.authClient });\n const requests = a.pageObjectIds.map(pageObjectId => ({\n updatePageProperties: {\n objectId: pageObjectId,\n pageProperties: {\n pageBackgroundFill: {\n solidFill: {\n color: {\n rgbColor: {\n red: a.backgroundColor.red || 0,\n green: a.backgroundColor.green || 0,\n blue: a.backgroundColor.blue || 0\n }\n },\n alpha: a.backgroundColor.alpha || 1\n }\n }\n },\n fields: 'pageBackgroundFill'\n }\n }));\n\n await slidesService.presentations.batchUpdate({\n presentationId: a.presentationId,\n requestBody: { requests }\n });\n\n return {\n content: [{ type: \"text\", text: `Set background color for ${a.pageObjectIds.length} slide(s)` }],\n isError: false\n };\n }\n\n case \"createGoogleSlidesTextBox\": {\n const validation = CreateGoogleSlidesTextBoxSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const slidesService = ctx.google.slides({ version: 'v1', auth: ctx.authClient });\n const elementId = `textBox_${uuidv4().substring(0, 8)}`;\n\n const requests: any[] = [\n {\n createShape: {\n objectId: elementId,\n shapeType: 'TEXT_BOX',\n elementProperties: {\n pageObjectId: a.pageObjectId,\n size: {\n width: { magnitude: a.width, unit: 'EMU' },\n height: { magnitude: a.height, unit: 'EMU' }\n },\n transform: {\n scaleX: 1,\n scaleY: 1,\n translateX: a.x,\n translateY: a.y,\n unit: 'EMU'\n }\n }\n }\n },\n {\n insertText: {\n objectId: elementId,\n text: a.text,\n insertionIndex: 0\n }\n }\n ];\n\n // Apply optional formatting\n if (a.fontSize || a.bold || a.italic) {\n const textStyle: any = {};\n const fields: string[] = [];\n\n if (a.fontSize) {\n textStyle.fontSize = {\n magnitude: a.fontSize,\n unit: 'PT'\n };\n fields.push('fontSize');\n }\n\n if (a.bold !== undefined) {\n textStyle.bold = a.bold;\n fields.push('bold');\n }\n\n if (a.italic !== undefined) {\n textStyle.italic = a.italic;\n fields.push('italic');\n }\n\n if (fields.length > 0) {\n requests.push({\n updateTextStyle: {\n objectId: elementId,\n style: textStyle,\n fields: fields.join(','),\n textRange: { type: 'ALL' }\n }\n });\n }\n }\n\n await slidesService.presentations.batchUpdate({\n presentationId: a.presentationId,\n requestBody: { requests }\n });\n\n return {\n content: [{ type: \"text\", text: `Created text box with ID: ${elementId}` }],\n isError: false\n };\n }\n\n case \"createGoogleSlidesShape\": {\n const validation = CreateGoogleSlidesShapeSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const slidesService = ctx.google.slides({ version: 'v1', auth: ctx.authClient });\n const elementId = `shape_${uuidv4().substring(0, 8)}`;\n\n const createRequest: any = {\n createShape: {\n objectId: elementId,\n shapeType: a.shapeType,\n elementProperties: {\n pageObjectId: a.pageObjectId,\n size: {\n width: { magnitude: a.width, unit: 'EMU' },\n height: { magnitude: a.height, unit: 'EMU' }\n },\n transform: {\n scaleX: 1,\n scaleY: 1,\n translateX: a.x,\n translateY: a.y,\n unit: 'EMU'\n }\n }\n }\n };\n\n const requests = [createRequest];\n\n // Apply background color if specified\n if (a.backgroundColor) {\n requests.push({\n updateShapeProperties: {\n objectId: elementId,\n shapeProperties: {\n shapeBackgroundFill: {\n solidFill: {\n color: {\n rgbColor: {\n red: a.backgroundColor.red || 0,\n green: a.backgroundColor.green || 0,\n blue: a.backgroundColor.blue || 0\n }\n },\n alpha: a.backgroundColor.alpha || 1\n }\n }\n },\n fields: 'shapeBackgroundFill'\n }\n });\n }\n\n await slidesService.presentations.batchUpdate({\n presentationId: a.presentationId,\n requestBody: { requests }\n });\n\n return {\n content: [{ type: \"text\", text: `Created ${a.shapeType} shape with ID: ${elementId}` }],\n isError: false\n };\n }\n\n case \"getGoogleSlidesSpeakerNotes\": {\n const validation = GetGoogleSlidesSpeakerNotesSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const slidesService = ctx.google.slides({ version: 'v1', auth: ctx.authClient });\n\n // Get the presentation to access the slide\n const presentation = await slidesService.presentations.get({\n presentationId: a.presentationId\n });\n\n if (!presentation.data.slides || a.slideIndex >= presentation.data.slides.length) {\n return errorResponse(`Slide index ${a.slideIndex} not found in presentation (has ${presentation.data.slides?.length ?? 0} slides)`);\n }\n\n const slide = presentation.data.slides[a.slideIndex];\n\n // Get the notes page object ID from the slide properties\n const notesObjectId = slide.slideProperties?.notesPage?.notesProperties?.speakerNotesObjectId;\n\n if (!notesObjectId) {\n return {\n content: [{ type: \"text\", text: \"No speaker notes found for this slide\" }],\n isError: false\n };\n }\n\n // Get the notes page to read the speaker notes text\n const notesPageObjectId = slide.slideProperties?.notesPage?.objectId;\n if (!notesPageObjectId) {\n return {\n content: [{ type: \"text\", text: \"No speaker notes found for this slide\" }],\n isError: false\n };\n }\n\n // Find the notes page for this slide\n const notesPage = presentation.data.slides?.[a.slideIndex]?.slideProperties?.notesPage;\n\n if (!notesPage || !notesPage.pageElements) {\n return {\n content: [{ type: \"text\", text: \"No speaker notes found for this slide\" }],\n isError: false\n };\n }\n\n // Find the speaker notes shape\n const speakerNotesElement = notesPage.pageElements.find(\n element => element.objectId === notesObjectId\n );\n\n if (!speakerNotesElement || !speakerNotesElement.shape?.text) {\n return {\n content: [{ type: \"text\", text: \"No speaker notes found for this slide\" }],\n isError: false\n };\n }\n\n // Extract the text from the speaker notes\n let notesText = '';\n const textElements = speakerNotesElement.shape.text.textElements || [];\n textElements.forEach((textElement) => {\n if (textElement.textRun?.content) {\n notesText += textElement.textRun.content;\n }\n });\n\n return {\n content: [{ type: \"text\", text: notesText.trim() || \"No speaker notes found for this slide\" }],\n isError: false\n };\n }\n\n case \"updateGoogleSlidesSpeakerNotes\": {\n const validation = UpdateGoogleSlidesSpeakerNotesSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const a = validation.data;\n\n const slidesService = ctx.google.slides({ version: 'v1', auth: ctx.authClient });\n\n // Get the presentation to access the slide\n const presentation = await slidesService.presentations.get({\n presentationId: a.presentationId\n });\n\n if (!presentation.data.slides || a.slideIndex >= presentation.data.slides.length) {\n return errorResponse(`Slide index ${a.slideIndex} not found in presentation (has ${presentation.data.slides?.length ?? 0} slides)`);\n }\n\n const slide = presentation.data.slides[a.slideIndex];\n\n // Get the notes page object ID from the slide properties\n const notesObjectId = slide.slideProperties?.notesPage?.notesProperties?.speakerNotesObjectId;\n\n if (!notesObjectId) {\n return errorResponse(\"This slide does not have a speaker notes object. Speaker notes may need to be initialized manually in Google Slides first.\");\n }\n\n // Create the batchUpdate request to replace the speaker notes text\n // Only delete existing text if there is any \u2014 deleteText with type:'ALL' fails on empty notes\n const notesPage = slide.slideProperties?.notesPage;\n const speakerNotesShape = notesPage?.pageElements?.find(\n (el: any) => el.objectId === notesObjectId\n );\n const existingTextElements = speakerNotesShape?.shape?.text?.textElements || [];\n const hasExistingText = existingTextElements.some(\n (el: any) => el.textRun?.content\n );\n\n const requests: any[] = [];\n\n if (hasExistingText) {\n requests.push({ deleteText: { objectId: notesObjectId, textRange: { type: 'ALL' } } });\n }\n\n requests.push({ insertText: { objectId: notesObjectId, text: a.notes, insertionIndex: 0 } });\n\n await slidesService.presentations.batchUpdate({\n presentationId: a.presentationId,\n requestBody: { requests }\n });\n\n return {\n content: [{ type: \"text\", text: `Successfully updated speaker notes for slide ${a.slideIndex}` }],\n isError: false\n };\n }\n\n case \"deleteGoogleSlide\": {\n const validation = DeleteGoogleSlideSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const a = validation.data;\n\n const slidesService = ctx.google.slides({ version: 'v1', auth: ctx.authClient });\n await slidesService.presentations.batchUpdate({\n presentationId: a.presentationId,\n requestBody: {\n requests: [{ deleteObject: { objectId: a.slideObjectId } }]\n }\n });\n\n return {\n content: [{ type: 'text', text: `Deleted slide ${a.slideObjectId}` }],\n isError: false,\n };\n }\n\n case \"duplicateSlide\": {\n const validation = DuplicateSlideSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const a = validation.data;\n\n const slidesService = ctx.google.slides({ version: 'v1', auth: ctx.authClient });\n const response = await slidesService.presentations.batchUpdate({\n presentationId: a.presentationId,\n requestBody: {\n requests: [{ duplicateObject: { objectId: a.slideObjectId } }]\n }\n });\n\n const dupId = response.data.replies?.[0]?.duplicateObject?.objectId;\n return {\n content: [{ type: 'text', text: `Duplicated slide ${a.slideObjectId}${dupId ? ` -> ${dupId}` : ''}` }],\n isError: false,\n };\n }\n\n case \"reorderSlides\": {\n const validation = ReorderSlidesSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const a = validation.data;\n\n const slidesService = ctx.google.slides({ version: 'v1', auth: ctx.authClient });\n await slidesService.presentations.batchUpdate({\n presentationId: a.presentationId,\n requestBody: {\n requests: [{\n updateSlidesPosition: {\n slideObjectIds: a.slideObjectIds,\n insertionIndex: a.insertionIndex,\n }\n }]\n }\n });\n\n return {\n content: [{ type: 'text', text: `Reordered ${a.slideObjectIds.length} slide(s) to index ${a.insertionIndex}` }],\n isError: false,\n };\n }\n\n case \"replaceAllTextInSlides\": {\n const validation = ReplaceAllTextInSlidesSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const a = validation.data;\n\n const slidesService = ctx.google.slides({ version: 'v1', auth: ctx.authClient });\n const response = await slidesService.presentations.batchUpdate({\n presentationId: a.presentationId,\n requestBody: {\n requests: [{\n replaceAllText: {\n containsText: {\n text: a.containsText,\n matchCase: a.matchCase,\n },\n replaceText: a.replaceText,\n }\n }]\n }\n });\n\n const count = response.data.replies?.[0]?.replaceAllText?.occurrencesChanged ?? 0;\n return {\n content: [{ type: 'text', text: `Replaced ${count} occurrence(s) of \"${a.containsText}\" in slides.` }],\n isError: false,\n };\n }\n\n case \"exportSlideThumbnail\": {\n const validation = ExportSlideThumbnailSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const a = validation.data;\n\n const slidesService = ctx.google.slides({ version: 'v1', auth: ctx.authClient });\n const response = await slidesService.presentations.pages.getThumbnail({\n presentationId: a.presentationId,\n pageObjectId: a.slideObjectId,\n 'thumbnailProperties.mimeType': a.mimeType,\n 'thumbnailProperties.thumbnailSize': a.size,\n });\n\n const url = response.data?.contentUrl;\n if (!url) return errorResponse('No thumbnail URL returned by Google Slides API.');\n\n return {\n content: [{ type: 'text', text: `Slide thumbnail URL (${a.mimeType}, ${a.size}): ${url}` }],\n isError: false,\n };\n }\n\n case \"getSlideElementInfo\": {\n const validation = GetSlideElementInfoSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const a = validation.data;\n\n const slidesService = ctx.google.slides({ version: 'v1', auth: ctx.authClient });\n\n // Page size lives on the presentation; grab just that field.\n const sizeOnly = await slidesService.presentations.get({\n presentationId: a.presentationId,\n fields: 'pageSize',\n });\n const slideWidth = sizeOnly.data.pageSize?.width?.magnitude || 9144000;\n const slideHeight = sizeOnly.data.pageSize?.height?.magnitude || 6858000;\n\n // If a specific slide is requested, fetch just that page. Otherwise fetch\n // only the fields of the slides we actually render.\n let slides: slides_v1.Schema$Page[] = [];\n if (a.slideObjectId) {\n const page = await slidesService.presentations.pages.get({\n presentationId: a.presentationId,\n pageObjectId: a.slideObjectId,\n fields: 'objectId,pageElements(objectId,transform,size,shape/shapeType,image)',\n });\n slides = [page.data];\n } else {\n const withSlides = await slidesService.presentations.get({\n presentationId: a.presentationId,\n fields: 'slides(objectId,pageElements(objectId,transform,size,shape/shapeType,image))',\n });\n slides = withSlides.data.slides || [];\n }\n\n const lines: string[] = [`Slide dimensions: ${slideWidth} x ${slideHeight} EMU`];\n for (const slide of slides) {\n lines.push(`\\n--- Slide: ${slide.objectId} ---`);\n for (const el of slide.pageElements || []) {\n const t = el.transform || {};\n const s = el.size || {};\n const intrW = s.width?.magnitude || 0;\n const intrH = s.height?.magnitude || 0;\n const scX = t.scaleX || 1;\n const scY = t.scaleY || 1;\n const tx = t.translateX || 0;\n const ty = t.translateY || 0;\n const renderedW = intrW * scX;\n const renderedH = intrH * scY;\n const right = tx + renderedW;\n const bottom = ty + renderedH;\n const offPage = (tx < 0 || ty < 0 || right > slideWidth || bottom > slideHeight)\n ? ' *** OFF PAGE ***' : '';\n lines.push(` ${el.objectId} (${el.shape ? 'shape:' + el.shape.shapeType : el.image ? 'image' : 'other'})`);\n lines.push(` intrinsic: ${intrW} x ${intrH}, scale: ${scX} x ${scY}`);\n lines.push(` rendered: ${Math.round(renderedW)} x ${Math.round(renderedH)} at (${tx}, ${ty})`);\n lines.push(` bounds: right=${Math.round(right)}, bottom=${Math.round(bottom)}${offPage}`);\n }\n }\n\n return { content: [{ type: 'text', text: lines.join('\\n') }], isError: false };\n }\n\n case \"moveSlideElement\": {\n const validation = MoveSlideElementSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const a = validation.data;\n\n const slidesService = ctx.google.slides({ version: 'v1', auth: ctx.authClient });\n\n // Field-masked fetch: we only need each element's objectId/transform/size.\n const pres = await slidesService.presentations.get({\n presentationId: a.presentationId,\n fields: 'slides(pageElements(objectId,transform,size))',\n });\n\n let currentTransform: slides_v1.Schema$AffineTransform | null = null;\n let currentSize: slides_v1.Schema$Size | null = null;\n for (const slide of pres.data.slides || []) {\n for (const el of slide.pageElements || []) {\n if (el.objectId === a.objectId) {\n currentTransform = el.transform || null;\n currentSize = el.size || null;\n break;\n }\n }\n if (currentTransform) break;\n }\n\n if (!currentTransform) {\n return errorResponse(`Element ${a.objectId} not found in presentation`);\n }\n\n const origWidth = currentSize?.width?.magnitude || 3000000;\n const origHeight = currentSize?.height?.magnitude || 3000000;\n const curScaleX = currentTransform.scaleX || 1;\n const curScaleY = currentTransform.scaleY || 1;\n\n const newScaleX = a.width !== undefined ? a.width / origWidth : curScaleX;\n const newScaleY = a.height !== undefined ? a.height / origHeight : curScaleY;\n const newX = a.x ?? (currentTransform.translateX || 0);\n const newY = a.y ?? (currentTransform.translateY || 0);\n\n const newTransform: slides_v1.Schema$AffineTransform = {\n scaleX: newScaleX,\n scaleY: newScaleY,\n translateX: newX,\n translateY: newY,\n shearX: currentTransform.shearX || 0,\n shearY: currentTransform.shearY || 0,\n unit: 'EMU',\n };\n\n const requests: slides_v1.Schema$Request[] = [{\n updatePageElementTransform: {\n objectId: a.objectId,\n applyMode: 'ABSOLUTE',\n transform: newTransform,\n },\n }];\n\n await slidesService.presentations.batchUpdate({\n presentationId: a.presentationId,\n requestBody: { requests },\n });\n\n const didResize = a.width !== undefined || a.height !== undefined;\n const action = didResize ? 'Moved/resized' : 'Moved';\n return {\n content: [{ type: 'text', text: `${action} element ${a.objectId} to (${newX}, ${newY})` }],\n isError: false,\n };\n }\n\n case \"deleteSlideElement\": {\n const validation = DeleteSlideElementSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const a = validation.data;\n\n const slidesService = ctx.google.slides({ version: 'v1', auth: ctx.authClient });\n await slidesService.presentations.batchUpdate({\n presentationId: a.presentationId,\n requestBody: {\n requests: [{ deleteObject: { objectId: a.objectId } }],\n },\n });\n\n return {\n content: [{ type: 'text', text: `Deleted element ${a.objectId}` }],\n isError: false,\n };\n }\n\n case \"insertSlidesImageFromUrl\": {\n const validation = InsertSlidesImageFromUrlSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const a = validation.data;\n return insertImageIntoSlide(ctx, a.presentationId, a.pageObjectId, a.imageUrl, a.x, a.y, a.width, a.height);\n }\n\n case \"insertSlidesLocalImage\": {\n const validation = InsertSlidesLocalImageSchema.safeParse(args);\n if (!validation.success) return errorResponse(validation.error.errors[0].message);\n const a = validation.data;\n\n // Upload briefly as public so the Slides API can fetch the bytes.\n const { fileId, webContentLink } = await uploadImageToDrive(ctx, a.localImagePath, {\n makePublic: true,\n });\n try {\n const result = await insertImageIntoSlide(\n ctx, a.presentationId, a.pageObjectId, webContentLink,\n a.x, a.y, a.width, a.height,\n );\n // Slides stores its own copy once createImage returns, so the intermediary\n // Drive file is no longer referenced. Delete it (which also removes the\n // public permission we just granted).\n await deleteDriveFile(ctx, fileId).catch((err) =>\n ctx.log(`insertSlidesLocalImage: failed to delete intermediary Drive file ${fileId}`, err),\n );\n return result;\n } catch (err) {\n // On embed failure, still try to clean up the uploaded file.\n await deleteDriveFile(ctx, fileId).catch(() => {});\n throw err;\n }\n }\n\n default:\n return null;\n }\n}\n", "import { z } from 'zod';\nimport { buildCalendarEventUpdate } from '../utils.js';\nimport { errorResponse } from '../types.js';\nimport type { ToolDefinition, ToolResult, ToolContext } from '../types.js';\n\n// ---------------------------------------------------------------------------\n// Interfaces\n// ---------------------------------------------------------------------------\n\ninterface CalendarEventInfo {\n id: string;\n summary?: string;\n description?: string;\n location?: string;\n start?: { dateTime?: string; date?: string; timeZone?: string };\n end?: { dateTime?: string; date?: string; timeZone?: string };\n status?: string;\n htmlLink?: string;\n hangoutLink?: string;\n meetingLink?: string;\n attendees?: { email: string; displayName?: string; responseStatus?: string }[];\n organizer?: { email?: string; displayName?: string };\n recurrence?: string[];\n created?: string;\n updated?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction formatCalendarEvent(event: any): CalendarEventInfo {\n const result: CalendarEventInfo = {\n id: event.id || '',\n summary: event.summary,\n description: event.description,\n location: event.location,\n status: event.status,\n htmlLink: event.htmlLink,\n created: event.created,\n updated: event.updated,\n };\n\n if (event.start) {\n result.start = {\n dateTime: event.start.dateTime,\n date: event.start.date,\n timeZone: event.start.timeZone,\n };\n }\n\n if (event.end) {\n result.end = {\n dateTime: event.end.dateTime,\n date: event.end.date,\n timeZone: event.end.timeZone,\n };\n }\n\n if (event.hangoutLink) {\n result.hangoutLink = event.hangoutLink;\n }\n\n if (event.conferenceData?.entryPoints) {\n const videoEntry = event.conferenceData.entryPoints.find((ep: any) => ep.entryPointType === 'video');\n if (videoEntry?.uri) {\n result.meetingLink = videoEntry.uri;\n }\n }\n\n if (event.attendees) {\n result.attendees = event.attendees.map((a: any) => ({\n email: a.email || '',\n displayName: a.displayName,\n responseStatus: a.responseStatus,\n }));\n }\n\n if (event.organizer) {\n result.organizer = {\n email: event.organizer.email,\n displayName: event.organizer.displayName,\n };\n }\n\n if (event.recurrence) {\n result.recurrence = event.recurrence;\n }\n\n return result;\n}\n\nfunction formatEventForDisplay(event: CalendarEventInfo): string {\n const lines: string[] = [];\n lines.push(`**${event.summary || '(No title)'}**`);\n\n if (event.start) {\n const startStr = event.start.dateTime || event.start.date || '';\n const endStr = event.end?.dateTime || event.end?.date || '';\n if (event.start.date) {\n // All-day event\n lines.push(`Date: ${startStr}${endStr && endStr !== startStr ? ` - ${endStr}` : ''}`);\n } else {\n lines.push(`Time: ${startStr} - ${endStr}`);\n }\n }\n\n if (event.location) lines.push(`Location: ${event.location}`);\n if (event.description) lines.push(`Description: ${event.description}`);\n if (event.hangoutLink || event.meetingLink) {\n lines.push(`Meeting: ${event.meetingLink || event.hangoutLink}`);\n }\n if (event.attendees && event.attendees.length > 0) {\n lines.push(`Attendees: ${event.attendees.map(a => a.email).join(', ')}`);\n }\n if (event.htmlLink) lines.push(`Link: ${event.htmlLink}`);\n lines.push(`Event ID: ${event.id}`);\n\n return lines.join('\\n');\n}\n\n// ---------------------------------------------------------------------------\n// Zod Schemas\n// ---------------------------------------------------------------------------\n\nconst ListCalendarsSchema = z.object({\n showHidden: z.boolean().optional().default(false).describe(\"Include hidden calendars\")\n});\n\nconst GetCalendarEventsSchema = z.object({\n calendarId: z.string().optional().default(\"primary\").describe(\"Calendar ID (default: primary)\"),\n timeMin: z.string().optional().describe(\"Start of time range (RFC3339, e.g., '2024-01-01T00:00:00Z')\"),\n timeMax: z.string().optional().describe(\"End of time range (RFC3339)\"),\n query: z.string().optional().describe(\"Free text search in events\"),\n maxResults: z.number().int().min(1).max(250).optional().default(50).describe(\"Maximum events to return (1-250)\"),\n singleEvents: z.boolean().optional().default(true).describe(\"Expand recurring events into instances\"),\n orderBy: z.enum([\"startTime\", \"updated\"]).optional().default(\"startTime\").describe(\"Sort order\")\n});\n\nconst GetCalendarEventSchema = z.object({\n eventId: z.string().min(1, \"Event ID is required\"),\n calendarId: z.string().optional().default(\"primary\").describe(\"Calendar ID (default: primary)\")\n});\n\nconst CreateCalendarEventSchema = z.object({\n summary: z.string().min(1, \"Event title is required\"),\n calendarId: z.string().optional().default(\"primary\").describe(\"Calendar ID (default: primary)\"),\n description: z.string().optional().describe(\"Event description\"),\n location: z.string().optional().describe(\"Event location\"),\n start: z.object({\n dateTime: z.string().optional().describe(\"RFC3339 timestamp for timed events\"),\n date: z.string().optional().describe(\"Date for all-day events (YYYY-MM-DD)\"),\n timeZone: z.string().optional().describe(\"Time zone (e.g., 'America/Los_Angeles')\")\n }).describe(\"Start time\"),\n end: z.object({\n dateTime: z.string().optional().describe(\"RFC3339 timestamp for timed events\"),\n date: z.string().optional().describe(\"Date for all-day events (YYYY-MM-DD)\"),\n timeZone: z.string().optional().describe(\"Time zone (e.g., 'America/Los_Angeles')\")\n }).describe(\"End time\"),\n attendees: z.array(z.string()).optional().describe(\"Email addresses of attendees\"),\n sendUpdates: z.enum([\"all\", \"externalOnly\", \"none\"]).optional().default(\"none\").describe(\"Send notifications to attendees (default: none)\"),\n conferenceType: z.enum([\"hangoutsMeet\"]).optional().describe(\"Add Google Meet link\"),\n recurrence: z.array(z.string()).optional().describe(\"RRULE strings for recurring events\"),\n visibility: z.enum([\"default\", \"public\", \"private\", \"confidential\"]).optional().describe(\"Event visibility\")\n});\n\nconst UpdateCalendarEventSchema = z.object({\n eventId: z.string().min(1, \"Event ID is required\"),\n calendarId: z.string().optional().default(\"primary\").describe(\"Calendar ID (default: primary)\"),\n summary: z.string().optional().describe(\"New event title\"),\n description: z.string().optional().describe(\"New event description\"),\n location: z.string().optional().describe(\"New event location\"),\n start: z.object({\n dateTime: z.string().optional(),\n date: z.string().optional(),\n timeZone: z.string().optional()\n }).optional().describe(\"New start time\"),\n end: z.object({\n dateTime: z.string().optional(),\n date: z.string().optional(),\n timeZone: z.string().optional()\n }).optional().describe(\"New end time\"),\n attendees: z.array(z.string()).optional().describe(\"Updated attendee emails (replaces existing)\"),\n sendUpdates: z.enum([\"all\", \"externalOnly\", \"none\"]).optional().default(\"none\").describe(\"Send notifications about the update (default: none)\")\n});\n\nconst DeleteCalendarEventSchema = z.object({\n eventId: z.string().min(1, \"Event ID is required\"),\n calendarId: z.string().optional().default(\"primary\").describe(\"Calendar ID (default: primary)\"),\n sendUpdates: z.enum([\"all\", \"externalOnly\", \"none\"]).optional().default(\"none\").describe(\"Send cancellation notifications to attendees (default: none)\")\n});\n\n// ---------------------------------------------------------------------------\n// Tool Definitions\n// ---------------------------------------------------------------------------\n\nexport const toolDefinitions: ToolDefinition[] = [\n {\n name: \"listCalendars\",\n description: \"List all accessible Google Calendars for the authenticated user\",\n inputSchema: {\n type: \"object\",\n properties: {\n showHidden: { type: \"boolean\", description: \"Include hidden calendars (default: false)\" }\n }\n }\n },\n {\n name: \"getCalendarEvents\",\n description: \"Get events from a Google Calendar with optional filtering\",\n inputSchema: {\n type: \"object\",\n properties: {\n calendarId: { type: \"string\", description: \"Calendar ID (default: primary)\" },\n timeMin: { type: \"string\", description: \"Start of time range (RFC3339, e.g., '2024-01-01T00:00:00Z')\" },\n timeMax: { type: \"string\", description: \"End of time range (RFC3339)\" },\n query: { type: \"string\", description: \"Free text search in events\" },\n maxResults: { type: \"number\", description: \"Maximum events to return (1-250, default: 50)\" },\n singleEvents: { type: \"boolean\", description: \"Expand recurring events into instances (default: true)\" },\n orderBy: { type: \"string\", enum: [\"startTime\", \"updated\"], description: \"Sort order (default: startTime)\" }\n }\n }\n },\n {\n name: \"getCalendarEvent\",\n description: \"Get a single calendar event by ID\",\n inputSchema: {\n type: \"object\",\n properties: {\n eventId: { type: \"string\", description: \"The event ID to retrieve\" },\n calendarId: { type: \"string\", description: \"Calendar ID (default: primary)\" }\n },\n required: [\"eventId\"]\n }\n },\n {\n name: \"createCalendarEvent\",\n description: \"Create a new calendar event. Supports timed events, all-day events, and Google Meet integration.\",\n inputSchema: {\n type: \"object\",\n properties: {\n summary: { type: \"string\", description: \"Event title\" },\n calendarId: { type: \"string\", description: \"Calendar ID (default: primary)\" },\n description: { type: \"string\", description: \"Event description\" },\n location: { type: \"string\", description: \"Event location\" },\n start: {\n type: \"object\",\n description: \"Start time (use dateTime for timed events, date for all-day)\",\n properties: {\n dateTime: { type: \"string\", description: \"RFC3339 timestamp (e.g., '2024-01-15T09:00:00-08:00')\" },\n date: { type: \"string\", description: \"Date for all-day events (YYYY-MM-DD)\" },\n timeZone: { type: \"string\", description: \"Time zone (e.g., 'America/Los_Angeles')\" }\n }\n },\n end: {\n type: \"object\",\n description: \"End time\",\n properties: {\n dateTime: { type: \"string\" },\n date: { type: \"string\" },\n timeZone: { type: \"string\" }\n }\n },\n attendees: { type: \"array\", items: { type: \"string\" }, description: \"Email addresses of attendees\" },\n sendUpdates: { type: \"string\", enum: [\"all\", \"externalOnly\", \"none\"], description: \"Send notifications (default: none)\" },\n conferenceType: { type: \"string\", enum: [\"hangoutsMeet\"], description: \"Add Google Meet link\" },\n recurrence: { type: \"array\", items: { type: \"string\" }, description: \"RRULE strings for recurring events\" },\n visibility: { type: \"string\", enum: [\"default\", \"public\", \"private\", \"confidential\"], description: \"Event visibility\" }\n },\n required: [\"summary\", \"start\", \"end\"]\n }\n },\n {\n name: \"updateCalendarEvent\",\n description: \"Update an existing calendar event\",\n inputSchema: {\n type: \"object\",\n properties: {\n eventId: { type: \"string\", description: \"The event ID to update\" },\n calendarId: { type: \"string\", description: \"Calendar ID (default: primary)\" },\n summary: { type: \"string\", description: \"New event title\" },\n description: { type: \"string\", description: \"New event description\" },\n location: { type: \"string\", description: \"New event location\" },\n start: {\n type: \"object\",\n properties: {\n dateTime: { type: \"string\" },\n date: { type: \"string\" },\n timeZone: { type: \"string\" }\n }\n },\n end: {\n type: \"object\",\n properties: {\n dateTime: { type: \"string\" },\n date: { type: \"string\" },\n timeZone: { type: \"string\" }\n }\n },\n attendees: { type: \"array\", items: { type: \"string\" }, description: \"Updated attendee emails (replaces existing)\" },\n sendUpdates: { type: \"string\", enum: [\"all\", \"externalOnly\", \"none\"], description: \"Send notifications (default: none)\" }\n },\n required: [\"eventId\"]\n }\n },\n {\n name: \"deleteCalendarEvent\",\n description: \"Delete a calendar event\",\n inputSchema: {\n type: \"object\",\n properties: {\n eventId: { type: \"string\", description: \"The event ID to delete\" },\n calendarId: { type: \"string\", description: \"Calendar ID (default: primary)\" },\n sendUpdates: { type: \"string\", enum: [\"all\", \"externalOnly\", \"none\"], description: \"Send cancellation notifications (default: none)\" }\n },\n required: [\"eventId\"]\n }\n }\n];\n\n// ---------------------------------------------------------------------------\n// Handler\n// ---------------------------------------------------------------------------\n\nexport async function handleTool(\n toolName: string,\n args: Record<string, unknown>,\n ctx: ToolContext,\n): Promise<ToolResult | null> {\n switch (toolName) {\n case \"listCalendars\": {\n const validation = ListCalendarsSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const parsed = validation.data;\n\n const response = await ctx.getCalendar().calendarList.list({\n showHidden: parsed.showHidden,\n maxResults: 250\n });\n\n const calendars = response.data.items || [];\n if (calendars.length === 0) {\n return { content: [{ type: \"text\", text: \"No calendars found.\" }], isError: false };\n }\n\n const lines = calendars.map((cal: any) => {\n const primary = cal.primary ? ' (PRIMARY)' : '';\n const role = cal.accessRole ? ` [${cal.accessRole}]` : '';\n return `- ${cal.summary}${primary}${role}\\n ID: ${cal.id}`;\n });\n\n return {\n content: [{ type: \"text\", text: `Found ${calendars.length} calendar(s):\\n\\n${lines.join('\\n\\n')}` }],\n isError: false\n };\n }\n\n case \"getCalendarEvents\": {\n const validation = GetCalendarEventsSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const parsed = validation.data;\n\n const params: any = {\n calendarId: parsed.calendarId || 'primary',\n maxResults: parsed.maxResults || 50,\n singleEvents: parsed.singleEvents !== false,\n orderBy: parsed.orderBy || 'startTime'\n };\n\n if (parsed.timeMin) params.timeMin = parsed.timeMin;\n if (parsed.timeMax) params.timeMax = parsed.timeMax;\n if (parsed.query) params.q = parsed.query;\n\n const response = await ctx.getCalendar().events.list(params);\n\n const events = response.data.items || [];\n if (events.length === 0) {\n return { content: [{ type: \"text\", text: \"No events found.\" }], isError: false };\n }\n\n const formattedEvents = events.map((e: any) => formatEventForDisplay(formatCalendarEvent(e)));\n\n return {\n content: [{ type: \"text\", text: `Found ${events.length} event(s):\\n\\n${formattedEvents.join('\\n\\n---\\n\\n')}` }],\n isError: false\n };\n }\n\n case \"getCalendarEvent\": {\n const validation = GetCalendarEventSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const parsed = validation.data;\n\n const response = await ctx.getCalendar().events.get({\n calendarId: parsed.calendarId || 'primary',\n eventId: parsed.eventId\n });\n\n const formatted = formatEventForDisplay(formatCalendarEvent(response.data));\n return {\n content: [{ type: \"text\", text: formatted }],\n isError: false\n };\n }\n\n case \"createCalendarEvent\": {\n const validation = CreateCalendarEventSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const parsed = validation.data;\n\n const eventResource: any = {\n summary: parsed.summary,\n description: parsed.description,\n location: parsed.location,\n start: parsed.start,\n end: parsed.end,\n visibility: parsed.visibility\n };\n\n if (parsed.attendees && parsed.attendees.length > 0) {\n eventResource.attendees = parsed.attendees.map((email: string) => ({ email }));\n }\n\n if (parsed.recurrence) {\n eventResource.recurrence = parsed.recurrence;\n }\n\n let conferenceDataVersion = 0;\n if (parsed.conferenceType === 'hangoutsMeet') {\n eventResource.conferenceData = {\n createRequest: {\n requestId: `meet-${Date.now()}`,\n conferenceSolutionKey: { type: 'hangoutsMeet' }\n }\n };\n conferenceDataVersion = 1;\n }\n\n const insertParams: any = {\n calendarId: parsed.calendarId || 'primary',\n requestBody: eventResource,\n sendUpdates: parsed.sendUpdates\n };\n\n if (conferenceDataVersion > 0) {\n insertParams.conferenceDataVersion = conferenceDataVersion;\n }\n\n const response = await ctx.getCalendar().events.insert(insertParams);\n const created = formatCalendarEvent(response.data);\n\n return {\n content: [{ type: \"text\", text: `Event created successfully!\\n\\n${formatEventForDisplay(created)}` }],\n isError: false\n };\n }\n\n case \"updateCalendarEvent\": {\n const validation = UpdateCalendarEventSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const parsed = validation.data;\n\n // First get the existing event\n const existingResponse = await ctx.getCalendar().events.get({\n calendarId: parsed.calendarId || 'primary',\n eventId: parsed.eventId\n });\n\n const existing = existingResponse.data;\n const eventResource = buildCalendarEventUpdate(existing, parsed);\n\n const response = await ctx.getCalendar().events.update({\n calendarId: parsed.calendarId || 'primary',\n eventId: parsed.eventId,\n requestBody: eventResource,\n sendUpdates: parsed.sendUpdates\n });\n\n const updated = formatCalendarEvent(response.data);\n\n return {\n content: [{ type: \"text\", text: `Event updated successfully!\\n\\n${formatEventForDisplay(updated)}` }],\n isError: false\n };\n }\n\n case \"deleteCalendarEvent\": {\n const validation = DeleteCalendarEventSchema.safeParse(args);\n if (!validation.success) {\n return errorResponse(validation.error.errors[0].message);\n }\n const parsed = validation.data;\n\n await ctx.getCalendar().events.delete({\n calendarId: parsed.calendarId || 'primary',\n eventId: parsed.eventId,\n sendUpdates: parsed.sendUpdates\n });\n\n return {\n content: [{ type: \"text\", text: `Event ${parsed.eventId} has been deleted.` }],\n isError: false\n };\n }\n\n default:\n return null;\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["__dirname", "OAuth2Client", "fs", "path", "OAuth2Client", "resolve", "OAuth2Client", "OAuth2Client", "resolve", "fileURLToPath", "join", "dirname", "existsSync", "statSync", "readFile", "writeFile", "basename", "extname", "join", "dirname", "join", "resolve", "log", "readFile", "join", "writeFile", "resolveParentPath", "existsSync", "statSync", "basename", "extname", "handleTool", "toolDefinitions", "z", "existsSync", "createReadStream", "basename", "extname", "z", "toolDefinitions", "handleTool", "document", "deleteEndIndex", "resolveInlineElementText", "extractSegments", "formatSegments", "hasFormattingInfo", "buildMetaLine", "trackFonts", "a", "extractText", "getContext", "handleTool", "toolDefinitions", "z", "z", "toolDefinitions", "handleTool", "handleTool", "toolDefinitions", "z", "z", "toolDefinitions", "handleTool", "handleTool", "toolDefinitions", "z", "z", "toolDefinitions", "handleTool", "FOLDER_MIME_TYPE", "fileURLToPath", "dirname", "join", "sid"]
|
|
7
7
|
}
|