@alanse/mcp-server-google-workspace 1.0.0 → 1.0.2

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.
Files changed (155) hide show
  1. package/README.md +146 -17
  2. package/dist/auth.js +5 -0
  3. package/dist/lib/calendar-helpers.js +197 -0
  4. package/dist/lib/drive-helpers.js +263 -0
  5. package/dist/lib/gmail-helpers.js +204 -0
  6. package/dist/tools/calendar/acl/calendar_acl_insert.js +80 -0
  7. package/dist/tools/calendar/acl/calendar_acl_list.js +82 -0
  8. package/dist/tools/calendar/basic/calendar_create_event.js +113 -0
  9. package/dist/tools/calendar/basic/calendar_delete_event.js +52 -0
  10. package/dist/tools/calendar/basic/calendar_get_event.js +52 -0
  11. package/dist/tools/calendar/basic/calendar_list_events.js +86 -0
  12. package/dist/tools/calendar/basic/calendar_update_event.js +116 -0
  13. package/dist/tools/calendar/calendarlist/calendar_calendarlist_get.js +73 -0
  14. package/dist/tools/calendar/calendarlist/calendar_calendarlist_list.js +87 -0
  15. package/dist/tools/calendar/calendars/calendar_calendars_get.js +52 -0
  16. package/dist/tools/calendar/calendars/calendar_calendars_insert.js +66 -0
  17. package/dist/tools/calendar/calendars/calendar_calendars_update.js +85 -0
  18. package/dist/tools/calendar/colors/calendar_colors_get.js +46 -0
  19. package/dist/tools/calendar/events_advanced/calendar_events_instances.js +81 -0
  20. package/dist/tools/calendar/events_advanced/calendar_events_move.js +63 -0
  21. package/dist/tools/calendar/events_advanced/calendar_events_quickadd.js +52 -0
  22. package/dist/tools/calendar/freebusy/calendar_freebusy_query.js +69 -0
  23. package/dist/tools/calendar/settings/calendar_settings_list.js +81 -0
  24. package/dist/tools/drive/advanced/drive_empty_trash.js +56 -0
  25. package/dist/tools/drive/advanced/drive_export_file.js +158 -0
  26. package/dist/tools/drive/advanced/drive_list_revisions.js +80 -0
  27. package/dist/tools/drive/basic/drive_get_metadata.js +49 -0
  28. package/dist/tools/drive/basic/drive_list_files.js +76 -0
  29. package/dist/tools/drive/file/drive_copy_file.js +79 -0
  30. package/dist/tools/drive/file/drive_create_file.js +72 -0
  31. package/dist/tools/drive/file/drive_delete_file.js +48 -0
  32. package/dist/tools/drive/file/drive_move_file.js +79 -0
  33. package/dist/tools/drive/file/drive_rename_file.js +58 -0
  34. package/dist/tools/drive/file/drive_update_file.js +106 -0
  35. package/dist/tools/drive/file/drive_upload_file.js +80 -0
  36. package/dist/tools/drive/folder/drive_create_folder.js +67 -0
  37. package/dist/tools/drive/folder/drive_list_folder_contents.js +68 -0
  38. package/dist/tools/drive/folder/drive_move_to_folder.js +59 -0
  39. package/dist/tools/drive/permissions/drive_list_permissions.js +115 -0
  40. package/dist/tools/drive/permissions/drive_remove_permission.js +71 -0
  41. package/dist/tools/drive/permissions/drive_share_file.js +116 -0
  42. package/dist/tools/drive/permissions/drive_update_permission.js +79 -0
  43. package/dist/tools/gmail/basic/gmail_get_message.js +95 -0
  44. package/dist/tools/gmail/basic/gmail_get_thread.js +46 -0
  45. package/dist/tools/gmail/basic/gmail_list_labels.js +54 -0
  46. package/dist/tools/gmail/basic/gmail_search_messages.js +59 -0
  47. package/dist/tools/gmail/batch/gmail_batch_modify_labels.js +74 -0
  48. package/dist/tools/gmail/batch/gmail_get_messages_batch.js +120 -0
  49. package/dist/tools/gmail/batch/gmail_get_threads_batch.js +102 -0
  50. package/dist/tools/gmail/labels/gmail_manage_label.js +131 -0
  51. package/dist/tools/gmail/labels/gmail_modify_labels.js +65 -0
  52. package/dist/tools/gmail/send/gmail_draft_message.js +117 -0
  53. package/dist/tools/gmail/send/gmail_send_message.js +109 -0
  54. package/dist/tools/index.js +267 -3
  55. package/package.json +8 -3
  56. package/dist/tools/basic/gsheets_add_sheet.js +0 -65
  57. package/dist/tools/basic/gsheets_copy_sheet.js +0 -56
  58. package/dist/tools/basic/gsheets_copy_to.js +0 -113
  59. package/dist/tools/basic/gsheets_create_spreadsheet.js +0 -88
  60. package/dist/tools/basic/gsheets_delete_columns.js +0 -69
  61. package/dist/tools/basic/gsheets_delete_rows.js +0 -69
  62. package/dist/tools/basic/gsheets_delete_sheet.js +0 -56
  63. package/dist/tools/basic/gsheets_duplicate_sheet.js +0 -72
  64. package/dist/tools/basic/gsheets_insert_columns.js +0 -69
  65. package/dist/tools/basic/gsheets_insert_rows.js +0 -69
  66. package/dist/tools/basic/gsheets_list_sheets.js +0 -53
  67. package/dist/tools/basic/gsheets_read.js +0 -120
  68. package/dist/tools/basic/gsheets_rename_sheet.js +0 -64
  69. package/dist/tools/charts/gsheets_add_bubble.js +0 -176
  70. package/dist/tools/charts/gsheets_add_candlestick.js +0 -192
  71. package/dist/tools/charts/gsheets_add_chart.js +0 -162
  72. package/dist/tools/charts/gsheets_add_combo.js +0 -169
  73. package/dist/tools/charts/gsheets_add_histogram.js +0 -143
  74. package/dist/tools/charts/gsheets_add_org_chart.js +0 -160
  75. package/dist/tools/charts/gsheets_add_treemap.js +0 -177
  76. package/dist/tools/charts/gsheets_add_waterfall.js +0 -155
  77. package/dist/tools/charts/gsheets_delete_chart.js +0 -56
  78. package/dist/tools/charts/gsheets_update_chart.js +0 -118
  79. package/dist/tools/data/gsheets_append_data.js +0 -68
  80. package/dist/tools/data/gsheets_batch_clear.js +0 -53
  81. package/dist/tools/data/gsheets_batch_update.js +0 -81
  82. package/dist/tools/data/gsheets_clear_data.js +0 -53
  83. package/dist/tools/data/gsheets_create_filter.js +0 -81
  84. package/dist/tools/data/gsheets_find_replace.js +0 -124
  85. package/dist/tools/data/gsheets_set_data_validation.js +0 -153
  86. package/dist/tools/data/gsheets_sort_range.js +0 -102
  87. package/dist/tools/data/gsheets_update_cell.js +0 -44
  88. package/dist/tools/formatting/gsheets_auto_resize.js +0 -75
  89. package/dist/tools/formatting/gsheets_format_cells.js +0 -161
  90. package/dist/tools/formatting/gsheets_freeze_columns.js +0 -67
  91. package/dist/tools/formatting/gsheets_freeze_rows.js +0 -67
  92. package/dist/tools/formatting/gsheets_merge_cells.js +0 -85
  93. package/dist/tools/formatting/gsheets_set_number_format.js +0 -116
  94. package/dist/tools/formatting/gsheets_unmerge_cells.js +0 -79
  95. package/dist/tools/formatting/gsheets_update_borders.js +0 -212
  96. package/dist/tools/gdrive/gdrive_read_file.js +0 -77
  97. package/dist/tools/gdrive/gdrive_search.js +0 -71
  98. package/dist/tools/gdrive_read_file.js +0 -77
  99. package/dist/tools/gdrive_search.js +0 -71
  100. package/dist/tools/gsheets_add_bubble.js +0 -176
  101. package/dist/tools/gsheets_add_candlestick.js +0 -192
  102. package/dist/tools/gsheets_add_chart.js +0 -162
  103. package/dist/tools/gsheets_add_combo.js +0 -169
  104. package/dist/tools/gsheets_add_conditional_format.js +0 -175
  105. package/dist/tools/gsheets_add_histogram.js +0 -143
  106. package/dist/tools/gsheets_add_named_range.js +0 -87
  107. package/dist/tools/gsheets_add_org_chart.js +0 -160
  108. package/dist/tools/gsheets_add_protected_range.js +0 -127
  109. package/dist/tools/gsheets_add_sheet.js +0 -65
  110. package/dist/tools/gsheets_add_treemap.js +0 -177
  111. package/dist/tools/gsheets_add_waterfall.js +0 -155
  112. package/dist/tools/gsheets_append_data.js +0 -68
  113. package/dist/tools/gsheets_auto_resize.js +0 -75
  114. package/dist/tools/gsheets_batch_clear.js +0 -53
  115. package/dist/tools/gsheets_batch_update.js +0 -81
  116. package/dist/tools/gsheets_clear_data.js +0 -53
  117. package/dist/tools/gsheets_copy_sheet.js +0 -56
  118. package/dist/tools/gsheets_copy_to.js +0 -113
  119. package/dist/tools/gsheets_create_filter.js +0 -81
  120. package/dist/tools/gsheets_create_spreadsheet.js +0 -88
  121. package/dist/tools/gsheets_delete_chart.js +0 -56
  122. package/dist/tools/gsheets_delete_columns.js +0 -69
  123. package/dist/tools/gsheets_delete_named_range.js +0 -56
  124. package/dist/tools/gsheets_delete_protected_range.js +0 -56
  125. package/dist/tools/gsheets_delete_rows.js +0 -69
  126. package/dist/tools/gsheets_delete_sheet.js +0 -56
  127. package/dist/tools/gsheets_duplicate_sheet.js +0 -72
  128. package/dist/tools/gsheets_find_replace.js +0 -124
  129. package/dist/tools/gsheets_format_cells.js +0 -161
  130. package/dist/tools/gsheets_freeze_columns.js +0 -67
  131. package/dist/tools/gsheets_freeze_rows.js +0 -67
  132. package/dist/tools/gsheets_insert_columns.js +0 -69
  133. package/dist/tools/gsheets_insert_rows.js +0 -69
  134. package/dist/tools/gsheets_list_sheets.js +0 -53
  135. package/dist/tools/gsheets_merge_cells.js +0 -85
  136. package/dist/tools/gsheets_read.js +0 -120
  137. package/dist/tools/gsheets_rename_sheet.js +0 -64
  138. package/dist/tools/gsheets_set_data_validation.js +0 -153
  139. package/dist/tools/gsheets_set_number_format.js +0 -116
  140. package/dist/tools/gsheets_sort_range.js +0 -102
  141. package/dist/tools/gsheets_unmerge_cells.js +0 -79
  142. package/dist/tools/gsheets_update_borders.js +0 -212
  143. package/dist/tools/gsheets_update_cell.js +0 -44
  144. package/dist/tools/gsheets_update_chart.js +0 -118
  145. package/dist/tools/gsheets_update_named_range.js +0 -112
  146. package/dist/tools/gsheets_update_protected_range.js +0 -110
  147. package/dist/tools/protection/gsheets_add_conditional_format.js +0 -175
  148. package/dist/tools/protection/gsheets_add_named_range.js +0 -87
  149. package/dist/tools/protection/gsheets_add_protected_range.js +0 -127
  150. package/dist/tools/protection/gsheets_delete_named_range.js +0 -56
  151. package/dist/tools/protection/gsheets_delete_protected_range.js +0 -56
  152. package/dist/tools/protection/gsheets_update_named_range.js +0 -112
  153. package/dist/tools/protection/gsheets_update_protected_range.js +0 -110
  154. /package/dist/tools/drive/{drive_read_file.js → basic/drive_read_file.js} +0 -0
  155. /package/dist/tools/drive/{drive_search.js → basic/drive_search.js} +0 -0
@@ -0,0 +1,79 @@
1
+ import { google } from "googleapis";
2
+ import { ResponseFormatter } from "../../../lib/response-formatter.js";
3
+ import { formatFileMetadata, generateDriveWebUrl, } from "../../../lib/drive-helpers.js";
4
+ export const schema = {
5
+ name: "drive_copy_file",
6
+ description: "Copy a file in Google Drive. Creates a duplicate of the file with optional new name and parent folder(s). Requires file ID.",
7
+ inputSchema: {
8
+ type: "object",
9
+ properties: {
10
+ fileId: {
11
+ type: "string",
12
+ description: "ID of the file to copy",
13
+ },
14
+ name: {
15
+ type: "string",
16
+ description: "Name for the copied file (optional, defaults to 'Copy of [original name]')",
17
+ optional: true,
18
+ },
19
+ parents: {
20
+ type: "array",
21
+ items: {
22
+ type: "string",
23
+ },
24
+ description: "Parent folder ID(s) for the copied file (optional, defaults to same location as original)",
25
+ optional: true,
26
+ },
27
+ },
28
+ required: ["fileId"],
29
+ },
30
+ };
31
+ export async function copyFile(args) {
32
+ try {
33
+ const drive = google.drive("v3");
34
+ const { fileId, name, parents } = args;
35
+ // Get original file metadata
36
+ const originalFile = await drive.files.get({
37
+ fileId,
38
+ fields: "id, name, mimeType",
39
+ });
40
+ const originalName = originalFile.data.name || "Unknown";
41
+ // Create copy metadata
42
+ const copyMetadata = {};
43
+ if (name) {
44
+ copyMetadata.name = name;
45
+ }
46
+ else {
47
+ copyMetadata.name = `Copy of ${originalName}`;
48
+ }
49
+ if (parents && parents.length > 0) {
50
+ copyMetadata.parents = parents;
51
+ }
52
+ // Copy the file
53
+ const response = await drive.files.copy({
54
+ fileId,
55
+ requestBody: copyMetadata,
56
+ fields: "id, name, mimeType, size, modifiedTime, webViewLink, parents",
57
+ });
58
+ const copiedFile = response.data;
59
+ const copiedFileId = copiedFile.id || "";
60
+ let output = `āœ… File copied successfully!\n\n`;
61
+ output += `šŸ“„ Original: ${originalName} (${fileId})\n`;
62
+ output += `šŸ“„ Copy: ${copiedFile.name} (${copiedFileId})\n\n`;
63
+ output += formatFileMetadata(copiedFile, true);
64
+ output += `\nšŸ“Ž Web URL: ${generateDriveWebUrl(copiedFileId)}\n`;
65
+ return ResponseFormatter.success({
66
+ originalFileId: fileId,
67
+ originalName,
68
+ copiedFileId,
69
+ copiedName: copiedFile.name,
70
+ mimeType: copiedFile.mimeType,
71
+ size: copiedFile.size,
72
+ webViewLink: copiedFile.webViewLink,
73
+ parents: copiedFile.parents,
74
+ }, output);
75
+ }
76
+ catch (error) {
77
+ return ResponseFormatter.error(error);
78
+ }
79
+ }
@@ -0,0 +1,72 @@
1
+ import { google } from "googleapis";
2
+ import { ResponseFormatter } from "../../../lib/response-formatter.js";
3
+ import { formatFileMetadata, generateDriveWebUrl, } from "../../../lib/drive-helpers.js";
4
+ export const schema = {
5
+ name: "drive_create_file",
6
+ description: "Create an empty file or Google Workspace document in Google Drive. Creates a file with metadata only (no content). Use drive_upload_file if you need to include content.",
7
+ inputSchema: {
8
+ type: "object",
9
+ properties: {
10
+ name: {
11
+ type: "string",
12
+ description: "File name",
13
+ },
14
+ mimeType: {
15
+ type: "string",
16
+ description: "MIME type of the file (e.g., 'application/vnd.google-apps.document' for Google Docs, 'application/vnd.google-apps.spreadsheet' for Sheets)",
17
+ },
18
+ parents: {
19
+ type: "array",
20
+ items: {
21
+ type: "string",
22
+ },
23
+ description: "Parent folder ID(s) where the file should be created",
24
+ optional: true,
25
+ },
26
+ description: {
27
+ type: "string",
28
+ description: "File description",
29
+ optional: true,
30
+ },
31
+ },
32
+ required: ["name", "mimeType"],
33
+ },
34
+ };
35
+ export async function createFile(args) {
36
+ try {
37
+ const drive = google.drive("v3");
38
+ const { name, mimeType, parents, description } = args;
39
+ // Create file metadata
40
+ const fileMetadata = {
41
+ name,
42
+ mimeType,
43
+ };
44
+ if (parents && parents.length > 0) {
45
+ fileMetadata.parents = parents;
46
+ }
47
+ if (description) {
48
+ fileMetadata.description = description;
49
+ }
50
+ // Create empty file
51
+ const response = await drive.files.create({
52
+ requestBody: fileMetadata,
53
+ fields: "id, name, mimeType, size, modifiedTime, webViewLink, parents",
54
+ });
55
+ const file = response.data;
56
+ const fileId = file.id || "";
57
+ let output = `āœ… File created successfully!\n\n`;
58
+ output += formatFileMetadata(file, true);
59
+ output += `\nšŸ“Ž Web URL: ${generateDriveWebUrl(fileId)}\n`;
60
+ return ResponseFormatter.success({
61
+ fileId,
62
+ name: file.name,
63
+ mimeType: file.mimeType,
64
+ size: file.size,
65
+ webViewLink: file.webViewLink,
66
+ parents: file.parents,
67
+ }, output);
68
+ }
69
+ catch (error) {
70
+ return ResponseFormatter.error(error);
71
+ }
72
+ }
@@ -0,0 +1,48 @@
1
+ import { google } from "googleapis";
2
+ import { ResponseFormatter } from "../../../lib/response-formatter.js";
3
+ export const schema = {
4
+ name: "drive_delete_file",
5
+ description: "Delete a file from Google Drive. Moves the file to trash. To permanently delete, use drive_empty_trash. Requires file ID.",
6
+ inputSchema: {
7
+ type: "object",
8
+ properties: {
9
+ fileId: {
10
+ type: "string",
11
+ description: "ID of the file to delete",
12
+ },
13
+ },
14
+ required: ["fileId"],
15
+ },
16
+ };
17
+ export async function deleteFile(args) {
18
+ try {
19
+ const drive = google.drive("v3");
20
+ const { fileId } = args;
21
+ // Get file metadata before deleting
22
+ const fileResponse = await drive.files.get({
23
+ fileId,
24
+ fields: "id, name, mimeType",
25
+ });
26
+ const fileName = fileResponse.data.name || "Unknown";
27
+ const mimeType = fileResponse.data.mimeType || "unknown";
28
+ // Delete the file (moves to trash)
29
+ await drive.files.delete({
30
+ fileId,
31
+ });
32
+ let output = `āœ… File deleted successfully!\n\n`;
33
+ output += `šŸ“„ File Details:\n`;
34
+ output += ` Name: ${fileName}\n`;
35
+ output += ` ID: ${fileId}\n`;
36
+ output += ` MIME Type: ${mimeType}\n`;
37
+ output += `\nNote: File moved to trash. Use drive_empty_trash to permanently delete.`;
38
+ return ResponseFormatter.success({
39
+ fileId,
40
+ name: fileName,
41
+ mimeType,
42
+ deleted: true,
43
+ }, output);
44
+ }
45
+ catch (error) {
46
+ return ResponseFormatter.error(error);
47
+ }
48
+ }
@@ -0,0 +1,79 @@
1
+ import { google } from "googleapis";
2
+ import { ResponseFormatter } from "../../../lib/response-formatter.js";
3
+ import { formatFileMetadata, generateDriveWebUrl, } from "../../../lib/drive-helpers.js";
4
+ export const schema = {
5
+ name: "drive_move_file",
6
+ description: "Move a file to a different folder in Google Drive. Updates the file's parent folder(s). Can optionally remove from existing parent folders. Requires file ID and new parent folder ID(s).",
7
+ inputSchema: {
8
+ type: "object",
9
+ properties: {
10
+ fileId: {
11
+ type: "string",
12
+ description: "ID of the file to move",
13
+ },
14
+ newParents: {
15
+ type: "array",
16
+ items: {
17
+ type: "string",
18
+ },
19
+ description: "New parent folder ID(s) to move the file to",
20
+ },
21
+ removeParents: {
22
+ type: "array",
23
+ items: {
24
+ type: "string",
25
+ },
26
+ description: "Parent folder ID(s) to remove the file from (optional, if not specified, removes from all current parents)",
27
+ optional: true,
28
+ },
29
+ },
30
+ required: ["fileId", "newParents"],
31
+ },
32
+ };
33
+ export async function moveFile(args) {
34
+ try {
35
+ const drive = google.drive("v3");
36
+ const { fileId, newParents, removeParents } = args;
37
+ // Get current file metadata
38
+ const fileResponse = await drive.files.get({
39
+ fileId,
40
+ fields: "id, name, parents",
41
+ });
42
+ const fileName = fileResponse.data.name || "Unknown";
43
+ const currentParents = fileResponse.data.parents || [];
44
+ // Determine which parents to remove
45
+ let parentsToRemove;
46
+ if (removeParents && removeParents.length > 0) {
47
+ parentsToRemove = removeParents;
48
+ }
49
+ else {
50
+ // Remove from all current parents if not specified
51
+ parentsToRemove = currentParents;
52
+ }
53
+ // Move the file
54
+ const response = await drive.files.update({
55
+ fileId,
56
+ addParents: newParents.join(","),
57
+ removeParents: parentsToRemove.join(","),
58
+ fields: "id, name, mimeType, size, modifiedTime, webViewLink, parents",
59
+ });
60
+ const movedFile = response.data;
61
+ let output = `āœ… File moved successfully!\n\n`;
62
+ output += `šŸ“„ File: ${fileName}\n`;
63
+ output += ` From: ${currentParents.join(", ") || "Root"}\n`;
64
+ output += ` To: ${newParents.join(", ")}\n\n`;
65
+ output += formatFileMetadata(movedFile, true);
66
+ output += `\nšŸ“Ž Web URL: ${generateDriveWebUrl(fileId)}\n`;
67
+ return ResponseFormatter.success({
68
+ fileId,
69
+ name: movedFile.name,
70
+ previousParents: currentParents,
71
+ newParents: movedFile.parents,
72
+ mimeType: movedFile.mimeType,
73
+ webViewLink: movedFile.webViewLink,
74
+ }, output);
75
+ }
76
+ catch (error) {
77
+ return ResponseFormatter.error(error);
78
+ }
79
+ }
@@ -0,0 +1,58 @@
1
+ import { google } from "googleapis";
2
+ import { ResponseFormatter } from "../../../lib/response-formatter.js";
3
+ import { formatFileMetadata, generateDriveWebUrl, } from "../../../lib/drive-helpers.js";
4
+ export const schema = {
5
+ name: "drive_rename_file",
6
+ description: "Rename a file in Google Drive. Updates the file's name while keeping all other properties unchanged. Requires file ID and new name.",
7
+ inputSchema: {
8
+ type: "object",
9
+ properties: {
10
+ fileId: {
11
+ type: "string",
12
+ description: "ID of the file to rename",
13
+ },
14
+ newName: {
15
+ type: "string",
16
+ description: "New name for the file",
17
+ },
18
+ },
19
+ required: ["fileId", "newName"],
20
+ },
21
+ };
22
+ export async function renameFile(args) {
23
+ try {
24
+ const drive = google.drive("v3");
25
+ const { fileId, newName } = args;
26
+ // Get current file metadata
27
+ const fileResponse = await drive.files.get({
28
+ fileId,
29
+ fields: "id, name, mimeType",
30
+ });
31
+ const oldName = fileResponse.data.name || "Unknown";
32
+ // Rename the file
33
+ const response = await drive.files.update({
34
+ fileId,
35
+ requestBody: {
36
+ name: newName,
37
+ },
38
+ fields: "id, name, mimeType, size, modifiedTime, webViewLink, parents",
39
+ });
40
+ const renamedFile = response.data;
41
+ let output = `āœ… File renamed successfully!\n\n`;
42
+ output += `šŸ“„ Old Name: ${oldName}\n`;
43
+ output += `šŸ“„ New Name: ${newName}\n\n`;
44
+ output += formatFileMetadata(renamedFile, true);
45
+ output += `\nšŸ“Ž Web URL: ${generateDriveWebUrl(fileId)}\n`;
46
+ return ResponseFormatter.success({
47
+ fileId,
48
+ oldName,
49
+ newName: renamedFile.name,
50
+ mimeType: renamedFile.mimeType,
51
+ size: renamedFile.size,
52
+ webViewLink: renamedFile.webViewLink,
53
+ }, output);
54
+ }
55
+ catch (error) {
56
+ return ResponseFormatter.error(error);
57
+ }
58
+ }
@@ -0,0 +1,106 @@
1
+ import { google } from "googleapis";
2
+ import { ResponseFormatter } from "../../../lib/response-formatter.js";
3
+ import { formatFileMetadata, generateDriveWebUrl, } from "../../../lib/drive-helpers.js";
4
+ export const schema = {
5
+ name: "drive_update_file",
6
+ description: "Update a file's metadata and/or content in Google Drive. Can update name, description, MIME type, and content. All update fields are optional - only provide the fields you want to update.",
7
+ inputSchema: {
8
+ type: "object",
9
+ properties: {
10
+ fileId: {
11
+ type: "string",
12
+ description: "ID of the file to update",
13
+ },
14
+ name: {
15
+ type: "string",
16
+ description: "New file name (optional)",
17
+ optional: true,
18
+ },
19
+ description: {
20
+ type: "string",
21
+ description: "New file description (optional)",
22
+ optional: true,
23
+ },
24
+ mimeType: {
25
+ type: "string",
26
+ description: "New MIME type (optional)",
27
+ optional: true,
28
+ },
29
+ content: {
30
+ type: "string",
31
+ description: "New file content (base64 encoded for binary files, plain text for text files) (optional)",
32
+ optional: true,
33
+ },
34
+ },
35
+ required: ["fileId"],
36
+ },
37
+ };
38
+ export async function updateFile(args) {
39
+ try {
40
+ const drive = google.drive("v3");
41
+ const { fileId, name, description, mimeType, content } = args;
42
+ // Get current file metadata
43
+ const fileResponse = await drive.files.get({
44
+ fileId,
45
+ fields: "id, name, description, mimeType",
46
+ });
47
+ const oldName = fileResponse.data.name || "Unknown";
48
+ const oldDescription = fileResponse.data.description || "";
49
+ const oldMimeType = fileResponse.data.mimeType || "unknown";
50
+ // Build update metadata
51
+ const updateMetadata = {};
52
+ const changes = [];
53
+ if (name !== undefined) {
54
+ updateMetadata.name = name;
55
+ changes.push(`Name: ${oldName} → ${name}`);
56
+ }
57
+ if (description !== undefined) {
58
+ updateMetadata.description = description;
59
+ changes.push(`Description: ${oldDescription || "(empty)"} → ${description}`);
60
+ }
61
+ if (mimeType !== undefined) {
62
+ updateMetadata.mimeType = mimeType;
63
+ changes.push(`MIME Type: ${oldMimeType} → ${mimeType}`);
64
+ }
65
+ // Update the file
66
+ const updateParams = {
67
+ fileId,
68
+ fields: "id, name, description, mimeType, size, modifiedTime, webViewLink, parents",
69
+ };
70
+ if (Object.keys(updateMetadata).length > 0) {
71
+ updateParams.requestBody = updateMetadata;
72
+ }
73
+ if (content !== undefined) {
74
+ updateParams.media = {
75
+ mimeType: mimeType || oldMimeType,
76
+ body: content,
77
+ };
78
+ changes.push("Content: Updated");
79
+ }
80
+ const response = await drive.files.update(updateParams);
81
+ const updatedFile = response.data;
82
+ let output = `āœ… File updated successfully!\n\n`;
83
+ if (changes.length > 0) {
84
+ output += `šŸ“ Changes:\n`;
85
+ changes.forEach((change) => {
86
+ output += ` • ${change}\n`;
87
+ });
88
+ output += `\n`;
89
+ }
90
+ output += formatFileMetadata(updatedFile, true);
91
+ output += `\nšŸ“Ž Web URL: ${generateDriveWebUrl(fileId)}\n`;
92
+ return ResponseFormatter.success({
93
+ fileId,
94
+ name: updatedFile.name,
95
+ description: updatedFile.description,
96
+ mimeType: updatedFile.mimeType,
97
+ size: updatedFile.size,
98
+ modifiedTime: updatedFile.modifiedTime,
99
+ webViewLink: updatedFile.webViewLink,
100
+ changes,
101
+ }, output);
102
+ }
103
+ catch (error) {
104
+ return ResponseFormatter.error(error);
105
+ }
106
+ }
@@ -0,0 +1,80 @@
1
+ import { google } from "googleapis";
2
+ import { ResponseFormatter } from "../../../lib/response-formatter.js";
3
+ import { formatFileMetadata, generateDriveWebUrl, } from "../../../lib/drive-helpers.js";
4
+ export const schema = {
5
+ name: "drive_upload_file",
6
+ description: "Upload a file to Google Drive with content. Creates a new file with the specified name, MIME type, and content. Optionally specify parent folder(s) and description.",
7
+ inputSchema: {
8
+ type: "object",
9
+ properties: {
10
+ name: {
11
+ type: "string",
12
+ description: "File name",
13
+ },
14
+ mimeType: {
15
+ type: "string",
16
+ description: "MIME type of the file (e.g., 'text/plain', 'application/json', 'image/png')",
17
+ },
18
+ content: {
19
+ type: "string",
20
+ description: "File content (base64 encoded for binary files, plain text for text files)",
21
+ },
22
+ parents: {
23
+ type: "array",
24
+ items: {
25
+ type: "string",
26
+ },
27
+ description: "Parent folder ID(s) where the file should be created",
28
+ optional: true,
29
+ },
30
+ description: {
31
+ type: "string",
32
+ description: "File description",
33
+ optional: true,
34
+ },
35
+ },
36
+ required: ["name", "mimeType", "content"],
37
+ },
38
+ };
39
+ export async function uploadFile(args) {
40
+ try {
41
+ const drive = google.drive("v3");
42
+ const { name, mimeType, content, parents, description } = args;
43
+ // Create file metadata
44
+ const fileMetadata = {
45
+ name,
46
+ mimeType,
47
+ };
48
+ if (parents && parents.length > 0) {
49
+ fileMetadata.parents = parents;
50
+ }
51
+ if (description) {
52
+ fileMetadata.description = description;
53
+ }
54
+ // Upload file with content
55
+ const response = await drive.files.create({
56
+ requestBody: fileMetadata,
57
+ media: {
58
+ mimeType,
59
+ body: content,
60
+ },
61
+ fields: "id, name, mimeType, size, modifiedTime, webViewLink, parents",
62
+ });
63
+ const file = response.data;
64
+ const fileId = file.id || "";
65
+ let output = `āœ… File uploaded successfully!\n\n`;
66
+ output += formatFileMetadata(file, true);
67
+ output += `\nšŸ“Ž Web URL: ${generateDriveWebUrl(fileId)}\n`;
68
+ return ResponseFormatter.success({
69
+ fileId,
70
+ name: file.name,
71
+ mimeType: file.mimeType,
72
+ size: file.size,
73
+ webViewLink: file.webViewLink,
74
+ parents: file.parents,
75
+ }, output);
76
+ }
77
+ catch (error) {
78
+ return ResponseFormatter.error(error);
79
+ }
80
+ }
@@ -0,0 +1,67 @@
1
+ import { google } from "googleapis";
2
+ import { ResponseFormatter } from "../../../lib/response-formatter.js";
3
+ import { formatFileMetadata, generateFolderWebUrl, FOLDER_MIME_TYPE, } from "../../../lib/drive-helpers.js";
4
+ export const schema = {
5
+ name: "drive_create_folder",
6
+ description: "Create a new folder in Google Drive. Can optionally place the folder inside a parent folder. Returns folder ID and metadata.",
7
+ inputSchema: {
8
+ type: "object",
9
+ properties: {
10
+ name: {
11
+ type: "string",
12
+ description: "Folder name",
13
+ },
14
+ parents: {
15
+ type: "array",
16
+ items: {
17
+ type: "string",
18
+ },
19
+ description: "Parent folder ID(s) where the folder should be created (optional)",
20
+ optional: true,
21
+ },
22
+ description: {
23
+ type: "string",
24
+ description: "Folder description",
25
+ optional: true,
26
+ },
27
+ },
28
+ required: ["name"],
29
+ },
30
+ };
31
+ export async function createFolder(args) {
32
+ try {
33
+ const drive = google.drive("v3");
34
+ const { name, parents, description } = args;
35
+ // Create folder metadata
36
+ const folderMetadata = {
37
+ name,
38
+ mimeType: FOLDER_MIME_TYPE,
39
+ };
40
+ if (parents && parents.length > 0) {
41
+ folderMetadata.parents = parents;
42
+ }
43
+ if (description) {
44
+ folderMetadata.description = description;
45
+ }
46
+ // Create folder
47
+ const response = await drive.files.create({
48
+ requestBody: folderMetadata,
49
+ fields: "id, name, mimeType, modifiedTime, webViewLink, parents",
50
+ });
51
+ const folder = response.data;
52
+ const folderId = folder.id || "";
53
+ let output = `āœ… Folder created successfully!\n\n`;
54
+ output += formatFileMetadata(folder, true);
55
+ output += `\nšŸ“‚ Web URL: ${generateFolderWebUrl(folderId)}\n`;
56
+ return ResponseFormatter.success({
57
+ folderId,
58
+ name: folder.name,
59
+ mimeType: folder.mimeType,
60
+ webViewLink: folder.webViewLink,
61
+ parents: folder.parents,
62
+ }, output);
63
+ }
64
+ catch (error) {
65
+ return ResponseFormatter.error(error);
66
+ }
67
+ }
@@ -0,0 +1,68 @@
1
+ import { google } from "googleapis";
2
+ import { ResponseFormatter } from "../../../lib/response-formatter.js";
3
+ import { formatFileList } from "../../../lib/drive-helpers.js";
4
+ export const schema = {
5
+ name: "drive_list_folder_contents",
6
+ description: "List all files and folders inside a specific folder in Google Drive. Supports pagination and sorting. Returns file IDs, names, types, and sizes.",
7
+ inputSchema: {
8
+ type: "object",
9
+ properties: {
10
+ folderId: {
11
+ type: "string",
12
+ description: "ID of the folder to list contents from",
13
+ },
14
+ pageSize: {
15
+ type: "number",
16
+ description: "Number of items to return per page (max 1000, default 100)",
17
+ optional: true,
18
+ },
19
+ pageToken: {
20
+ type: "string",
21
+ description: "Page token for pagination",
22
+ optional: true,
23
+ },
24
+ orderBy: {
25
+ type: "string",
26
+ description: "Sort order (e.g., 'name', 'modifiedTime desc', 'createdTime')",
27
+ optional: true,
28
+ },
29
+ },
30
+ required: ["folderId"],
31
+ },
32
+ };
33
+ export async function listFolderContents(args) {
34
+ try {
35
+ const drive = google.drive("v3");
36
+ const { folderId, pageSize = 100, pageToken, orderBy } = args;
37
+ // Build query for folder contents
38
+ const q = `'${folderId}' in parents and trashed = false`;
39
+ const response = await drive.files.list({
40
+ q,
41
+ pageSize: Math.min(pageSize, 1000),
42
+ pageToken,
43
+ orderBy: orderBy || "modifiedTime desc",
44
+ fields: "nextPageToken, files(id, name, mimeType, size, modifiedTime, createdTime, webViewLink, parents, iconLink)",
45
+ });
46
+ const files = response.data.files || [];
47
+ const nextPageToken = response.data.nextPageToken;
48
+ let output = `šŸ“ Folder Contents\n`;
49
+ output += `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n`;
50
+ output += `Folder ID: ${folderId}\n\n`;
51
+ output += formatFileList(files, nextPageToken);
52
+ return ResponseFormatter.success({
53
+ folderId,
54
+ count: files.length,
55
+ files: files.map((f) => ({
56
+ id: f.id,
57
+ name: f.name,
58
+ mimeType: f.mimeType,
59
+ size: f.size,
60
+ modifiedTime: f.modifiedTime,
61
+ })),
62
+ nextPageToken,
63
+ }, output);
64
+ }
65
+ catch (error) {
66
+ return ResponseFormatter.error(error);
67
+ }
68
+ }