@aaronsb/google-workspace-mcp 2.6.1 → 2.7.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.
Files changed (68) hide show
  1. package/README.md +2 -2
  2. package/build/__tests__/factory/calendar-patch.test.js +79 -0
  3. package/build/__tests__/factory/calendar-patch.test.js.map +1 -1
  4. package/build/__tests__/factory/drive-patch.test.js +224 -0
  5. package/build/__tests__/factory/drive-patch.test.js.map +1 -1
  6. package/build/__tests__/factory/sheets-patch.test.js +71 -6
  7. package/build/__tests__/factory/sheets-patch.test.js.map +1 -1
  8. package/build/__tests__/server/formatting/html-sanitize.test.d.ts +7 -0
  9. package/build/__tests__/server/formatting/html-sanitize.test.js +174 -0
  10. package/build/__tests__/server/formatting/html-sanitize.test.js.map +1 -0
  11. package/build/__tests__/server/formatting/markdown.test.js +55 -0
  12. package/build/__tests__/server/formatting/markdown.test.js.map +1 -1
  13. package/build/__tests__/server/handlers/calendar.test.js +2 -1
  14. package/build/__tests__/server/handlers/calendar.test.js.map +1 -1
  15. package/build/executor/gws.js +41 -20
  16. package/build/executor/gws.js.map +1 -1
  17. package/build/factory/generator.d.ts +11 -3
  18. package/build/factory/generator.js +41 -16
  19. package/build/factory/generator.js.map +1 -1
  20. package/build/factory/manifest/README.md +12 -0
  21. package/build/factory/manifest/calendar.yaml +204 -0
  22. package/build/factory/manifest/docs.yaml +77 -0
  23. package/build/factory/manifest/drive.yaml +314 -0
  24. package/build/factory/manifest/gmail.yaml +272 -0
  25. package/build/factory/manifest/meet.yaml +159 -0
  26. package/build/factory/manifest/sheets.yaml +225 -0
  27. package/build/factory/manifest/tasks.yaml +137 -0
  28. package/build/factory/registry.d.ts +3 -3
  29. package/build/factory/registry.js +5 -5
  30. package/build/factory/registry.js.map +1 -1
  31. package/build/factory/types.d.ts +6 -0
  32. package/build/server/formatting/html-sanitize.d.ts +40 -0
  33. package/build/server/formatting/html-sanitize.js +146 -0
  34. package/build/server/formatting/html-sanitize.js.map +1 -0
  35. package/build/server/formatting/markdown.d.ts +13 -3
  36. package/build/server/formatting/markdown.js +33 -6
  37. package/build/server/formatting/markdown.js.map +1 -1
  38. package/build/server/handlers/calendar.js +1 -1
  39. package/build/server/handlers/calendar.js.map +1 -1
  40. package/build/server/scratchpad/__tests__/docs-sync-integration.test.d.ts +11 -0
  41. package/build/server/scratchpad/__tests__/docs-sync-integration.test.js +187 -0
  42. package/build/server/scratchpad/__tests__/docs-sync-integration.test.js.map +1 -0
  43. package/build/server/scratchpad/__tests__/docs-sync.test.d.ts +16 -0
  44. package/build/server/scratchpad/__tests__/docs-sync.test.js +213 -0
  45. package/build/server/scratchpad/__tests__/docs-sync.test.js.map +1 -0
  46. package/build/server/scratchpad/adapters/import-doc.js +6 -3
  47. package/build/server/scratchpad/adapters/import-doc.js.map +1 -1
  48. package/build/server/scratchpad/adapters/send-calendar.js +1 -1
  49. package/build/server/scratchpad/adapters/send-calendar.js.map +1 -1
  50. package/build/server/scratchpad/docs-sync.d.ts +65 -0
  51. package/build/server/scratchpad/docs-sync.js +191 -0
  52. package/build/server/scratchpad/docs-sync.js.map +1 -0
  53. package/build/server/scratchpad/handler.js +95 -14
  54. package/build/server/scratchpad/handler.js.map +1 -1
  55. package/build/server/scratchpad/manager.d.ts +7 -0
  56. package/build/server/scratchpad/manager.js.map +1 -1
  57. package/build/services/calendar/patch.js +72 -1
  58. package/build/services/calendar/patch.js.map +1 -1
  59. package/build/services/drive/patch.js +170 -0
  60. package/build/services/drive/patch.js.map +1 -1
  61. package/build/services/gmail/patch.js +7 -2
  62. package/build/services/gmail/patch.js.map +1 -1
  63. package/build/services/sheets/patch.js +57 -6
  64. package/build/services/sheets/patch.js.map +1 -1
  65. package/build/version.d.ts +1 -1
  66. package/build/version.js +1 -1
  67. package/package.json +4 -2
  68. package/build/factory/manifest.yaml +0 -1383
@@ -0,0 +1,314 @@
1
+ tool_name: manage_drive
2
+ description: "Search, upload, download, share, comment on, or manage files in Google Drive."
3
+ requires_email: true
4
+ gws_service: drive
5
+ operations:
6
+
7
+ # --- File discovery ---
8
+
9
+ search:
10
+ type: list
11
+ description: "find files by query"
12
+ resource: files.list
13
+ params:
14
+ query:
15
+ type: string
16
+ description: "Drive search query (e.g. \"name contains 'budget'\" or \"mimeType='application/pdf'\")"
17
+ maps_to: q
18
+ maxResults:
19
+ type: number
20
+ description: "Max results (default: 10, max: 50)"
21
+ default: 10
22
+ max: 50
23
+ maps_to: pageSize
24
+ defaults:
25
+ fields: "files(id, name, mimeType, modifiedTime, size, webViewLink)"
26
+ supportsAllDrives: true
27
+ includeItemsFromAllDrives: true
28
+
29
+ get:
30
+ type: detail
31
+ description: "get file metadata"
32
+ resource: files.get
33
+ params:
34
+ fileId:
35
+ type: string
36
+ description: "File ID"
37
+ required: true
38
+ defaults:
39
+ fields: "id, name, mimeType, modifiedTime, size, webViewLink, owners, shared, parents"
40
+ supportsAllDrives: true
41
+
42
+ # --- File operations ---
43
+
44
+ upload:
45
+ type: action
46
+ description: "upload a local file to Drive"
47
+ helper: "+upload"
48
+ params:
49
+ filePath:
50
+ type: string
51
+ description: "Local file path to upload"
52
+ required: true
53
+ name:
54
+ type: string
55
+ description: "File name in Drive (defaults to local name)"
56
+ parentFolderId:
57
+ type: string
58
+ description: "Destination folder ID"
59
+ cli_args:
60
+ name: "--name"
61
+ parentFolderId: "--parent"
62
+
63
+ viewImage:
64
+ type: detail
65
+ description: "view an image file inline without saving to workspace (png, jpg, gif, webp). Use for quick preview — use download to save."
66
+ resource: files.get
67
+ params:
68
+ fileId:
69
+ type: string
70
+ description: "File ID of the image to view"
71
+ required: true
72
+ defaults:
73
+ supportsAllDrives: true
74
+
75
+ download:
76
+ type: detail
77
+ description: "download file content to local path"
78
+ resource: files.get
79
+ params:
80
+ fileId:
81
+ type: string
82
+ description: "File ID to download"
83
+ required: true
84
+ outputPath:
85
+ type: string
86
+ description: "Local path to save the file"
87
+ defaults:
88
+ alt: media
89
+ supportsAllDrives: true
90
+
91
+ copy:
92
+ type: action
93
+ description: "create a copy of a file (set name to rename the copy; parentFolderId to place it in a folder)"
94
+ resource: files.copy
95
+ params:
96
+ fileId:
97
+ type: string
98
+ description: "File ID to copy"
99
+ required: true
100
+ name:
101
+ type: string
102
+ description: "Name for the copy (without it, Drive names it 'Copy of <original>')"
103
+ parentFolderId:
104
+ type: string
105
+ description: "Folder ID to place the copy in (defaults to the source's folder)"
106
+ defaults:
107
+ supportsAllDrives: true
108
+
109
+ update:
110
+ type: action
111
+ description: "rename a file (set name) and/or move it between folders (addParents / removeParents — to move, set both)"
112
+ resource: files.update
113
+ params:
114
+ fileId:
115
+ type: string
116
+ description: "File ID to update"
117
+ required: true
118
+ name:
119
+ type: string
120
+ description: "New file name (rename)"
121
+ addParents:
122
+ type: string
123
+ description: "Comma-separated folder ID(s) to add as parents (move into a folder)"
124
+ removeParents:
125
+ type: string
126
+ description: "Comma-separated folder ID(s) to remove as parents (move out of a folder)"
127
+ defaults:
128
+ supportsAllDrives: true
129
+
130
+ delete:
131
+ type: action
132
+ description: "permanently delete a file (cannot be undone)"
133
+ resource: files.delete
134
+ params:
135
+ fileId:
136
+ type: string
137
+ description: "File ID to delete"
138
+ required: true
139
+ defaults:
140
+ supportsAllDrives: true
141
+
142
+ export:
143
+ type: action
144
+ description: "export a Google Workspace document (Docs, Sheets, Slides) to a file format"
145
+ resource: files.export
146
+ params:
147
+ fileId:
148
+ type: string
149
+ description: "File ID to export"
150
+ required: true
151
+ mimeType:
152
+ type: string
153
+ description: "Target format (e.g. application/pdf, text/csv, text/plain, application/vnd.openxmlformats-officedocument.wordprocessingml.document)"
154
+ required: true
155
+ outputPath:
156
+ type: string
157
+ description: "Local path to save exported file"
158
+ defaults:
159
+ supportsAllDrives: true
160
+
161
+ # --- Sharing ---
162
+
163
+ listPermissions:
164
+ type: list
165
+ description: "list sharing permissions on a file"
166
+ resource: permissions.list
167
+ params:
168
+ fileId:
169
+ type: string
170
+ description: "File ID"
171
+ required: true
172
+ defaults:
173
+ supportsAllDrives: true
174
+
175
+ share:
176
+ type: action
177
+ description: "share a file with a user, group, domain, or anyone"
178
+ resource: permissions.create
179
+ params:
180
+ fileId:
181
+ type: string
182
+ description: "File ID to share"
183
+ required: true
184
+ shareEmail:
185
+ type: string
186
+ description: "Email address (required when type is 'user' or 'group'). Omit for 'domain' (use 'domain' param) or 'anyone'."
187
+ role:
188
+ type: string
189
+ description: "Permission level"
190
+ enum: [reader, commenter, writer, organizer]
191
+ default: reader
192
+ type:
193
+ type: string
194
+ description: "Permission type (default: 'user'). Use 'group' for Google Groups, 'domain' to share with an entire G Suite domain, 'anyone' for public links."
195
+ enum: [user, group, domain, anyone]
196
+ default: user
197
+ domain:
198
+ type: string
199
+ description: "Domain name (required when type is 'domain')."
200
+ defaults:
201
+ supportsAllDrives: true
202
+
203
+ unshare:
204
+ type: action
205
+ description: "remove sharing permission from a file"
206
+ resource: permissions.delete
207
+ params:
208
+ fileId:
209
+ type: string
210
+ description: "File ID"
211
+ required: true
212
+ permissionId:
213
+ type: string
214
+ description: "Permission ID to remove (from listPermissions)"
215
+ required: true
216
+ defaults:
217
+ supportsAllDrives: true
218
+
219
+ # --- Comments ---
220
+
221
+ listComments:
222
+ type: list
223
+ description: "list comments on a file"
224
+ resource: comments.list
225
+ params:
226
+ fileId:
227
+ type: string
228
+ description: "File ID"
229
+ required: true
230
+ includeDeleted:
231
+ type: boolean
232
+ description: "Include deleted comments (default: false)"
233
+ defaults:
234
+ fields: "comments(id, content, htmlContent, author(displayName, emailAddress), createdTime, modifiedTime, resolved, quotedFileContent, replies(id, content, htmlContent, author(displayName), createdTime)), nextPageToken"
235
+ supportsAllDrives: true
236
+
237
+ getComment:
238
+ type: detail
239
+ description: "get a specific comment by ID"
240
+ resource: comments.get
241
+ params:
242
+ fileId:
243
+ type: string
244
+ description: "File ID"
245
+ required: true
246
+ commentId:
247
+ type: string
248
+ description: "Comment ID"
249
+ required: true
250
+ defaults:
251
+ fields: "id, content, htmlContent, author(displayName, emailAddress), createdTime, modifiedTime, resolved, quotedFileContent, replies(id, content, htmlContent, author(displayName), createdTime)"
252
+ supportsAllDrives: true
253
+
254
+ addComment:
255
+ type: action
256
+ description: "add a comment to a file (optionally anchored to quoted text)"
257
+ resource: comments.create
258
+ params:
259
+ fileId:
260
+ type: string
261
+ description: "File ID"
262
+ required: true
263
+ content:
264
+ type: string
265
+ description: "Comment text"
266
+ required: true
267
+ quotedText:
268
+ type: string
269
+ description: "Text to anchor the comment to (optional — if provided, comment is anchored to first occurrence)"
270
+ defaults:
271
+ fields: "id, content, htmlContent, author(displayName), createdTime, quotedFileContent"
272
+ supportsAllDrives: true
273
+
274
+ resolveComment:
275
+ type: action
276
+ description: "resolve or reopen a comment"
277
+ resource: comments.update
278
+ params:
279
+ fileId:
280
+ type: string
281
+ description: "File ID"
282
+ required: true
283
+ commentId:
284
+ type: string
285
+ description: "Comment ID"
286
+ required: true
287
+ resolved:
288
+ type: boolean
289
+ description: "true to resolve, false to reopen"
290
+ required: true
291
+ defaults:
292
+ fields: "id, content, resolved"
293
+ supportsAllDrives: true
294
+
295
+ replyToComment:
296
+ type: action
297
+ description: "reply to an existing comment"
298
+ resource: replies.create
299
+ params:
300
+ fileId:
301
+ type: string
302
+ description: "File ID"
303
+ required: true
304
+ commentId:
305
+ type: string
306
+ description: "Comment ID to reply to"
307
+ required: true
308
+ content:
309
+ type: string
310
+ description: "Reply text"
311
+ required: true
312
+ defaults:
313
+ fields: "id, content, htmlContent, author(displayName), createdTime"
314
+ supportsAllDrives: true
@@ -0,0 +1,272 @@
1
+ tool_name: manage_email
2
+ description: "Search, read, send, forward, or manage emails in a Google Workspace account. Supports Gmail search syntax."
3
+ requires_email: true
4
+ gws_service: gmail
5
+ operations:
6
+
7
+ # --- Core message operations ---
8
+
9
+ search:
10
+ type: list
11
+ description: "find emails by query"
12
+ resource: users.messages.list
13
+ params:
14
+ query:
15
+ type: string
16
+ description: 'Gmail search query (e.g. "from:alice subject:meeting has:attachment")'
17
+ maps_to: q
18
+ maxResults:
19
+ type: number
20
+ description: "Max results (default: 10, max: 50)"
21
+ default: 10
22
+ max: 50
23
+ defaults:
24
+ userId: me
25
+ hydration:
26
+ resource: users.messages.get
27
+ format: metadata
28
+ headers: [From, Subject, Date]
29
+
30
+ read:
31
+ type: detail
32
+ description: "get full email by ID. Pass bodyFormat: 'html' when the plain-text part is a stub (marketing email, invitations, booking confirmations) and the dates/codes you need only exist in the HTML — returned HTML is sanitized and wrapped in a Spotlighting block (ADR-305)."
33
+ resource: users.messages.get
34
+ params:
35
+ messageId:
36
+ type: string
37
+ description: "Email message ID"
38
+ required: true
39
+ maps_to: id
40
+ bodyFormat:
41
+ type: string
42
+ description: "How to render the message body. 'plain' (default) returns text/plain or a crude HTML-strip fallback. 'html' returns the text/html part sanitized — useful when the plain-text part is empty/stub."
43
+ enum: [plain, html]
44
+ default: plain
45
+ client_only: true
46
+ defaults:
47
+ userId: me
48
+
49
+ send:
50
+ type: action
51
+ description: "compose and send a new email (creates draft when attachments present, 35MB attachment limit via upload endpoint)"
52
+ helper: "+send"
53
+ params:
54
+ to:
55
+ type: string
56
+ description: "Recipient email(s), comma-separated"
57
+ required: true
58
+ subject:
59
+ type: string
60
+ description: "Email subject line"
61
+ required: true
62
+ body:
63
+ type: string
64
+ description: "Email body text"
65
+ required: true
66
+ cc:
67
+ type: string
68
+ description: "CC email(s), comma-separated"
69
+ bcc:
70
+ type: string
71
+ description: "BCC email(s), comma-separated"
72
+ attachments:
73
+ type: string
74
+ description: "Workspace filenames to attach, comma-separated (files must exist in workspace via manage_workspace). Creates draft when present."
75
+ html:
76
+ type: boolean
77
+ description: "Treat body as HTML content (default: plain text)"
78
+ draft:
79
+ type: boolean
80
+ description: "Save as draft instead of sending (default: false, forced true when attachments present)"
81
+ cli_args:
82
+ to: "--to"
83
+ subject: "--subject"
84
+ body: "--body"
85
+ cc: "--cc"
86
+ bcc: "--bcc"
87
+
88
+ reply:
89
+ type: action
90
+ description: "reply to a message (thread-aware)"
91
+ helper: "+reply"
92
+ params:
93
+ messageId:
94
+ type: string
95
+ description: "Message ID to reply to"
96
+ required: true
97
+ body:
98
+ type: string
99
+ description: "Reply body text"
100
+ required: true
101
+ cli_args:
102
+ messageId: "--message-id"
103
+ body: "--body"
104
+
105
+ replyAll:
106
+ type: action
107
+ description: "reply-all to a message (thread-aware, includes all recipients)"
108
+ helper: "+reply-all"
109
+ params:
110
+ messageId:
111
+ type: string
112
+ description: "Message ID to reply to"
113
+ required: true
114
+ body:
115
+ type: string
116
+ description: "Reply body text"
117
+ required: true
118
+ cc:
119
+ type: string
120
+ description: "Additional CC email(s), comma-separated"
121
+ cli_args:
122
+ messageId: "--message-id"
123
+ body: "--body"
124
+ cc: "--cc"
125
+
126
+ forward:
127
+ type: action
128
+ description: "forward a message to new recipients (includes original attachments by default)"
129
+ helper: "+forward"
130
+ params:
131
+ messageId:
132
+ type: string
133
+ description: "Message ID to forward"
134
+ required: true
135
+ to:
136
+ type: string
137
+ description: "Recipient email(s), comma-separated"
138
+ required: true
139
+ body:
140
+ type: string
141
+ description: "Optional note to prepend above forwarded message"
142
+ cli_args:
143
+ messageId: "--message-id"
144
+ to: "--to"
145
+ body: "--body"
146
+
147
+ # --- Inbox management ---
148
+
149
+ triage:
150
+ type: list
151
+ description: "unread inbox summary (sender, subject, date)"
152
+ helper: "+triage"
153
+
154
+ trash:
155
+ type: action
156
+ description: "move a message to trash"
157
+ resource: users.messages.trash
158
+ params:
159
+ messageId:
160
+ type: string
161
+ description: "Message ID to trash"
162
+ required: true
163
+ maps_to: id
164
+ defaults:
165
+ userId: me
166
+
167
+ untrash:
168
+ type: action
169
+ description: "restore a message from trash"
170
+ resource: users.messages.untrash
171
+ params:
172
+ messageId:
173
+ type: string
174
+ description: "Message ID to restore"
175
+ required: true
176
+ maps_to: id
177
+ defaults:
178
+ userId: me
179
+
180
+ getAttachment:
181
+ type: detail
182
+ description: "download an email attachment to workspace directory (use read first to see attachment list)"
183
+ resource: users.messages.attachments.get
184
+ params:
185
+ messageId:
186
+ type: string
187
+ description: "Message ID containing the attachment"
188
+ required: true
189
+ filename:
190
+ type: string
191
+ description: "Filename to save as (from the read response, e.g. 'invoice_template.md')"
192
+ required: true
193
+ defaults:
194
+ userId: me
195
+
196
+ viewAttachment:
197
+ type: detail
198
+ description: "view an image attachment inline without saving to workspace (png, jpg, gif, webp). Use for quick preview — use getAttachment to save."
199
+ resource: users.messages.attachments.get
200
+ params:
201
+ messageId:
202
+ type: string
203
+ description: "Message ID containing the attachment"
204
+ required: true
205
+ filename:
206
+ type: string
207
+ description: "Image filename from the read response"
208
+ required: true
209
+ defaults:
210
+ userId: me
211
+
212
+ modify:
213
+ type: action
214
+ description: "add or remove labels on a message (e.g. archive, mark read/unread)"
215
+ resource: users.messages.modify
216
+ params:
217
+ messageId:
218
+ type: string
219
+ description: "Message ID to modify"
220
+ required: true
221
+ maps_to: id
222
+ addLabelIds:
223
+ type: string
224
+ description: "Comma-separated label IDs to add (e.g. STARRED, IMPORTANT, Label_123)"
225
+ removeLabelIds:
226
+ type: string
227
+ description: "Comma-separated label IDs to remove (e.g. UNREAD, INBOX to archive)"
228
+ defaults:
229
+ userId: me
230
+
231
+ # --- Labels ---
232
+
233
+ labels:
234
+ type: list
235
+ description: "list all labels in the mailbox"
236
+ resource: users.labels.list
237
+ defaults:
238
+ userId: me
239
+
240
+ # --- Threads ---
241
+
242
+ threads:
243
+ type: list
244
+ description: "list email threads by query"
245
+ resource: users.threads.list
246
+ params:
247
+ query:
248
+ type: string
249
+ description: "Gmail search query to filter threads"
250
+ maps_to: q
251
+ maxResults:
252
+ type: number
253
+ description: "Max threads to return (default: 10, max: 50)"
254
+ default: 10
255
+ max: 50
256
+ defaults:
257
+ userId: me
258
+
259
+ getThread:
260
+ type: detail
261
+ description: "get all messages in a thread"
262
+ resource: users.threads.get
263
+ params:
264
+ threadId:
265
+ type: string
266
+ description: "Thread ID to retrieve"
267
+ required: true
268
+ maps_to: id
269
+ defaults:
270
+ userId: me
271
+ format: metadata
272
+ metadataHeaders: "From,Subject,Date,To"