@aaronsb/google-workspace-mcp 2.0.0-alpha.4

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 (184) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +193 -0
  3. package/build/__helpers__/testSetup.d.ts +1 -0
  4. package/build/__helpers__/testSetup.js +6 -0
  5. package/build/__helpers__/testSetup.js.map +1 -0
  6. package/build/__tests__/accounts/credentials.test.d.ts +1 -0
  7. package/build/__tests__/accounts/credentials.test.js +129 -0
  8. package/build/__tests__/accounts/credentials.test.js.map +1 -0
  9. package/build/__tests__/accounts/registry.test.d.ts +1 -0
  10. package/build/__tests__/accounts/registry.test.js +74 -0
  11. package/build/__tests__/accounts/registry.test.js.map +1 -0
  12. package/build/__tests__/executor/errors.test.d.ts +1 -0
  13. package/build/__tests__/executor/errors.test.js +42 -0
  14. package/build/__tests__/executor/errors.test.js.map +1 -0
  15. package/build/__tests__/executor/gws.test.d.ts +1 -0
  16. package/build/__tests__/executor/gws.test.js +178 -0
  17. package/build/__tests__/executor/gws.test.js.map +1 -0
  18. package/build/__tests__/executor/paths.test.d.ts +1 -0
  19. package/build/__tests__/executor/paths.test.js +60 -0
  20. package/build/__tests__/executor/paths.test.js.map +1 -0
  21. package/build/__tests__/executor/workspace.test.d.ts +1 -0
  22. package/build/__tests__/executor/workspace.test.js +117 -0
  23. package/build/__tests__/executor/workspace.test.js.map +1 -0
  24. package/build/__tests__/factory/generator.test.d.ts +1 -0
  25. package/build/__tests__/factory/generator.test.js +178 -0
  26. package/build/__tests__/factory/generator.test.js.map +1 -0
  27. package/build/__tests__/factory/patch-coverage.test.d.ts +10 -0
  28. package/build/__tests__/factory/patch-coverage.test.js +148 -0
  29. package/build/__tests__/factory/patch-coverage.test.js.map +1 -0
  30. package/build/__tests__/factory/safety.test.d.ts +1 -0
  31. package/build/__tests__/factory/safety.test.js +107 -0
  32. package/build/__tests__/factory/safety.test.js.map +1 -0
  33. package/build/__tests__/integration/executor.test.d.ts +5 -0
  34. package/build/__tests__/integration/executor.test.js +46 -0
  35. package/build/__tests__/integration/executor.test.js.map +1 -0
  36. package/build/__tests__/integration/handlers.test.d.ts +6 -0
  37. package/build/__tests__/integration/handlers.test.js +95 -0
  38. package/build/__tests__/integration/handlers.test.js.map +1 -0
  39. package/build/__tests__/integration/setup.d.ts +19 -0
  40. package/build/__tests__/integration/setup.js +61 -0
  41. package/build/__tests__/integration/setup.js.map +1 -0
  42. package/build/__tests__/server/formatting/markdown.test.d.ts +1 -0
  43. package/build/__tests__/server/formatting/markdown.test.js +149 -0
  44. package/build/__tests__/server/formatting/markdown.test.js.map +1 -0
  45. package/build/__tests__/server/formatting/next-steps.test.d.ts +1 -0
  46. package/build/__tests__/server/formatting/next-steps.test.js +42 -0
  47. package/build/__tests__/server/formatting/next-steps.test.js.map +1 -0
  48. package/build/__tests__/server/handler.test.d.ts +1 -0
  49. package/build/__tests__/server/handler.test.js +97 -0
  50. package/build/__tests__/server/handler.test.js.map +1 -0
  51. package/build/__tests__/server/handlers/__mocks__/executor.d.ts +147 -0
  52. package/build/__tests__/server/handlers/__mocks__/executor.js +114 -0
  53. package/build/__tests__/server/handlers/__mocks__/executor.js.map +1 -0
  54. package/build/__tests__/server/handlers/accounts.test.d.ts +1 -0
  55. package/build/__tests__/server/handlers/accounts.test.js +127 -0
  56. package/build/__tests__/server/handlers/accounts.test.js.map +1 -0
  57. package/build/__tests__/server/handlers/calendar.test.d.ts +1 -0
  58. package/build/__tests__/server/handlers/calendar.test.js +95 -0
  59. package/build/__tests__/server/handlers/calendar.test.js.map +1 -0
  60. package/build/__tests__/server/handlers/drive.test.d.ts +1 -0
  61. package/build/__tests__/server/handlers/drive.test.js +81 -0
  62. package/build/__tests__/server/handlers/drive.test.js.map +1 -0
  63. package/build/__tests__/server/handlers/email.test.d.ts +1 -0
  64. package/build/__tests__/server/handlers/email.test.js +99 -0
  65. package/build/__tests__/server/handlers/email.test.js.map +1 -0
  66. package/build/__tests__/server/handlers/validate.test.d.ts +1 -0
  67. package/build/__tests__/server/handlers/validate.test.js +88 -0
  68. package/build/__tests__/server/handlers/validate.test.js.map +1 -0
  69. package/build/__tests__/server/queue.test.d.ts +1 -0
  70. package/build/__tests__/server/queue.test.js +194 -0
  71. package/build/__tests__/server/queue.test.js.map +1 -0
  72. package/build/__tests__/server/server.test.d.ts +7 -0
  73. package/build/__tests__/server/server.test.js +135 -0
  74. package/build/__tests__/server/server.test.js.map +1 -0
  75. package/build/__tests__/server/tools.test.d.ts +1 -0
  76. package/build/__tests__/server/tools.test.js +91 -0
  77. package/build/__tests__/server/tools.test.js.map +1 -0
  78. package/build/accounts/auth.d.ts +24 -0
  79. package/build/accounts/auth.js +118 -0
  80. package/build/accounts/auth.js.map +1 -0
  81. package/build/accounts/credentials.d.ts +11 -0
  82. package/build/accounts/credentials.js +52 -0
  83. package/build/accounts/credentials.js.map +1 -0
  84. package/build/accounts/index.d.ts +6 -0
  85. package/build/accounts/index.js +4 -0
  86. package/build/accounts/index.js.map +1 -0
  87. package/build/accounts/registry.d.ts +11 -0
  88. package/build/accounts/registry.js +62 -0
  89. package/build/accounts/registry.js.map +1 -0
  90. package/build/executor/errors.d.ts +15 -0
  91. package/build/executor/errors.js +37 -0
  92. package/build/executor/errors.js.map +1 -0
  93. package/build/executor/file-output.d.ts +23 -0
  94. package/build/executor/file-output.js +67 -0
  95. package/build/executor/file-output.js.map +1 -0
  96. package/build/executor/gws.d.ts +23 -0
  97. package/build/executor/gws.js +144 -0
  98. package/build/executor/gws.js.map +1 -0
  99. package/build/executor/index.d.ts +4 -0
  100. package/build/executor/index.js +4 -0
  101. package/build/executor/index.js.map +1 -0
  102. package/build/executor/paths.d.ts +6 -0
  103. package/build/executor/paths.js +25 -0
  104. package/build/executor/paths.js.map +1 -0
  105. package/build/executor/workspace.d.ts +38 -0
  106. package/build/executor/workspace.js +146 -0
  107. package/build/executor/workspace.js.map +1 -0
  108. package/build/factory/defaults.d.ts +8 -0
  109. package/build/factory/defaults.js +101 -0
  110. package/build/factory/defaults.js.map +1 -0
  111. package/build/factory/generator.d.ts +23 -0
  112. package/build/factory/generator.js +253 -0
  113. package/build/factory/generator.js.map +1 -0
  114. package/build/factory/manifest.yaml +852 -0
  115. package/build/factory/patches.d.ts +6 -0
  116. package/build/factory/patches.js +13 -0
  117. package/build/factory/patches.js.map +1 -0
  118. package/build/factory/registry.d.ts +12 -0
  119. package/build/factory/registry.js +18 -0
  120. package/build/factory/registry.js.map +1 -0
  121. package/build/factory/safety.d.ts +68 -0
  122. package/build/factory/safety.js +157 -0
  123. package/build/factory/safety.js.map +1 -0
  124. package/build/factory/types.d.ts +102 -0
  125. package/build/factory/types.js +6 -0
  126. package/build/factory/types.js.map +1 -0
  127. package/build/factory/yaml.d.ts +2 -0
  128. package/build/factory/yaml.js +3 -0
  129. package/build/factory/yaml.js.map +1 -0
  130. package/build/index.d.ts +2 -0
  131. package/build/index.js +14 -0
  132. package/build/index.js.map +1 -0
  133. package/build/server/formatting/markdown.d.ts +21 -0
  134. package/build/server/formatting/markdown.js +324 -0
  135. package/build/server/formatting/markdown.js.map +1 -0
  136. package/build/server/formatting/next-steps.d.ts +9 -0
  137. package/build/server/formatting/next-steps.js +123 -0
  138. package/build/server/formatting/next-steps.js.map +1 -0
  139. package/build/server/handler.d.ts +3 -0
  140. package/build/server/handler.js +24 -0
  141. package/build/server/handler.js.map +1 -0
  142. package/build/server/handlers/accounts.d.ts +2 -0
  143. package/build/server/handlers/accounts.js +181 -0
  144. package/build/server/handlers/accounts.js.map +1 -0
  145. package/build/server/handlers/calendar.d.ts +2 -0
  146. package/build/server/handlers/calendar.js +93 -0
  147. package/build/server/handlers/calendar.js.map +1 -0
  148. package/build/server/handlers/drive.d.ts +2 -0
  149. package/build/server/handlers/drive.js +74 -0
  150. package/build/server/handlers/drive.js.map +1 -0
  151. package/build/server/handlers/email.d.ts +2 -0
  152. package/build/server/handlers/email.js +115 -0
  153. package/build/server/handlers/email.js.map +1 -0
  154. package/build/server/handlers/validate.d.ts +3 -0
  155. package/build/server/handlers/validate.js +22 -0
  156. package/build/server/handlers/validate.js.map +1 -0
  157. package/build/server/handlers/workspace.d.ts +9 -0
  158. package/build/server/handlers/workspace.js +110 -0
  159. package/build/server/handlers/workspace.js.map +1 -0
  160. package/build/server/index.d.ts +4 -0
  161. package/build/server/index.js +4 -0
  162. package/build/server/index.js.map +1 -0
  163. package/build/server/queue.d.ts +11 -0
  164. package/build/server/queue.js +141 -0
  165. package/build/server/queue.js.map +1 -0
  166. package/build/server/server.d.ts +3 -0
  167. package/build/server/server.js +214 -0
  168. package/build/server/server.js.map +1 -0
  169. package/build/server/tools.d.ts +13 -0
  170. package/build/server/tools.js +99 -0
  171. package/build/server/tools.js.map +1 -0
  172. package/build/services/calendar/patch.d.ts +11 -0
  173. package/build/services/calendar/patch.js +116 -0
  174. package/build/services/calendar/patch.js.map +1 -0
  175. package/build/services/drive/patch.d.ts +10 -0
  176. package/build/services/drive/patch.js +131 -0
  177. package/build/services/drive/patch.js.map +1 -0
  178. package/build/services/gmail/attachments.d.ts +19 -0
  179. package/build/services/gmail/attachments.js +90 -0
  180. package/build/services/gmail/attachments.js.map +1 -0
  181. package/build/services/gmail/patch.d.ts +10 -0
  182. package/build/services/gmail/patch.js +226 -0
  183. package/build/services/gmail/patch.js.map +1 -0
  184. package/package.json +34 -0
@@ -0,0 +1,181 @@
1
+ import { listAccounts, removeAccount, authenticateAndAddAccount } from '../../accounts/registry.js';
2
+ import { checkAccountStatus, reauthWithServices } from '../../accounts/auth.js';
3
+ import { exportAndSaveCredential } from '../../accounts/credentials.js';
4
+ import { nextSteps } from '../formatting/next-steps.js';
5
+ import { getActivePolicies } from '../../factory/safety.js';
6
+ import { manifest } from '../../factory/registry.js';
7
+ import { checkWorkspaceStatus } from '../../executor/workspace.js';
8
+ function formatAccountList(accounts) {
9
+ const lines = accounts.map(a => {
10
+ const cred = a.hasCredential ? '[x]' : '[ ]';
11
+ const desc = a.description ? ` — ${a.description}` : '';
12
+ return `${cred} ${a.email} (${a.category})${desc}`;
13
+ });
14
+ return {
15
+ text: `## Accounts (${accounts.length})\n\n${lines.join('\n')}`,
16
+ refs: {
17
+ count: accounts.length,
18
+ accounts: accounts.map(a => a.email),
19
+ email: accounts[0]?.email,
20
+ },
21
+ };
22
+ }
23
+ function formatStatus(status) {
24
+ const valid = status.tokenValid ? '[x] Token valid' : '[ ] Token invalid';
25
+ const refresh = status.hasRefreshToken ? '[x] Has refresh token' : '[ ] No refresh token';
26
+ const scopeList = status.scopes.length > 0
27
+ ? status.scopes.map(s => `- ${s.replace('https://www.googleapis.com/auth/', '')}`).join('\n')
28
+ : '(no scopes)';
29
+ return {
30
+ text: [
31
+ `## Account Status: ${status.email}`,
32
+ '',
33
+ valid,
34
+ refresh,
35
+ `**Scopes (${status.scopeCount}):**`,
36
+ scopeList,
37
+ ].join('\n'),
38
+ refs: {
39
+ email: status.email,
40
+ tokenValid: status.tokenValid,
41
+ scopeCount: status.scopeCount,
42
+ scopes: status.scopes,
43
+ },
44
+ };
45
+ }
46
+ export async function handleAccounts(params) {
47
+ const operation = params.operation;
48
+ switch (operation) {
49
+ case 'list': {
50
+ process.stderr.write(`[gws-mcp] accounts.list: reading accounts file\n`);
51
+ const accounts = await listAccounts();
52
+ process.stderr.write(`[gws-mcp] accounts.list: found ${accounts.length} accounts\n`);
53
+ if (accounts.length === 0) {
54
+ return {
55
+ text: 'No accounts configured.' + nextSteps('accounts', 'list_empty'),
56
+ refs: { count: 0 },
57
+ };
58
+ }
59
+ const formatted = formatAccountList(accounts);
60
+ return {
61
+ text: formatted.text + nextSteps('accounts', 'list'),
62
+ refs: formatted.refs,
63
+ };
64
+ }
65
+ case 'authenticate': {
66
+ const clientId = process.env.GOOGLE_CLIENT_ID;
67
+ const clientSecret = process.env.GOOGLE_CLIENT_SECRET;
68
+ if (!clientId || !clientSecret) {
69
+ throw new Error('GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET environment variables are required. ' +
70
+ 'Create OAuth credentials at https://console.cloud.google.com/apis/credentials');
71
+ }
72
+ const category = params.category || 'personal';
73
+ const description = params.description;
74
+ const result = await authenticateAndAddAccount(clientId, clientSecret, category, description);
75
+ const statusText = result.status === 'success'
76
+ ? `Account authenticated: **${result.account}**`
77
+ : `Authentication failed: ${result.error}`;
78
+ return {
79
+ text: statusText + nextSteps('accounts', 'authenticate'),
80
+ refs: { status: result.status, account: result.account, email: result.account },
81
+ };
82
+ }
83
+ case 'remove': {
84
+ const email = params.email;
85
+ if (!email)
86
+ throw new Error('email is required for remove');
87
+ await removeAccount(email);
88
+ return {
89
+ text: `Account removed: ${email}` + nextSteps('accounts', 'remove'),
90
+ refs: { status: 'removed', email },
91
+ };
92
+ }
93
+ case 'status': {
94
+ const email = params.email;
95
+ if (!email)
96
+ throw new Error('email is required for status');
97
+ const status = await checkAccountStatus(email);
98
+ const formatted = formatStatus(status);
99
+ return {
100
+ text: formatted.text + nextSteps('accounts', 'status', { email }),
101
+ refs: formatted.refs,
102
+ };
103
+ }
104
+ case 'refresh': {
105
+ const email = params.email;
106
+ if (!email)
107
+ throw new Error('email is required for refresh');
108
+ const credPath = await exportAndSaveCredential(email);
109
+ return {
110
+ text: `Credentials refreshed for ${email}` + nextSteps('accounts', 'refresh', { email }),
111
+ refs: { status: 'refreshed', email, credentialPath: credPath },
112
+ };
113
+ }
114
+ case 'scopes': {
115
+ const email = params.email;
116
+ const services = params.services;
117
+ if (!email)
118
+ throw new Error('email is required for scopes');
119
+ if (!services)
120
+ throw new Error('services is required for scopes (comma-separated: gmail,drive,calendar,sheets,etc.)');
121
+ const clientId = process.env.GOOGLE_CLIENT_ID;
122
+ const clientSecret = process.env.GOOGLE_CLIENT_SECRET;
123
+ if (!clientId || !clientSecret) {
124
+ throw new Error('GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET environment variables are required');
125
+ }
126
+ const result = await reauthWithServices(clientId, clientSecret, services);
127
+ const statusText = result.status === 'success'
128
+ ? `Scopes updated for **${result.account}** with services: ${services}`
129
+ : `Scope update failed: ${result.error}`;
130
+ return {
131
+ text: statusText + nextSteps('accounts', 'scopes', { email }),
132
+ refs: { status: result.status, email: result.account, services },
133
+ };
134
+ }
135
+ case 'capabilities': {
136
+ const policies = getActivePolicies();
137
+ const services = Object.entries(manifest.services).map(([name, def]) => ({
138
+ service: name,
139
+ tool: def.tool_name,
140
+ operations: Object.keys(def.operations),
141
+ }));
142
+ const workspace = checkWorkspaceStatus();
143
+ const parts = [];
144
+ // Services
145
+ const totalOps = services.reduce((sum, s) => sum + s.operations.length, 0);
146
+ parts.push(`## Services (${services.length} services, ${totalOps} operations)\n`);
147
+ for (const s of services) {
148
+ parts.push(`**${s.tool}** (${s.operations.length}): ${s.operations.join(', ')}`);
149
+ }
150
+ // Safety policies
151
+ parts.push('');
152
+ if (policies.length > 0) {
153
+ parts.push(`## Safety Policies (${policies.length} active)\n`);
154
+ for (const p of policies) {
155
+ parts.push(`- **${p.name}**: ${p.description}`);
156
+ }
157
+ }
158
+ else {
159
+ parts.push('## Safety Policies\n\nNo safety policies active — all operations are allowed.');
160
+ }
161
+ // Workspace
162
+ parts.push('');
163
+ parts.push('## Workspace Directory\n');
164
+ parts.push(`**Path:** ${workspace.path}`);
165
+ parts.push(`**Status:** ${workspace.valid ? 'valid' : 'invalid — ' + workspace.warning}`);
166
+ return {
167
+ text: parts.join('\n'),
168
+ refs: {
169
+ totalServices: services.length,
170
+ totalOperations: totalOps,
171
+ activePolicies: policies.map(p => p.name),
172
+ workspacePath: workspace.path,
173
+ workspaceValid: workspace.valid,
174
+ },
175
+ };
176
+ }
177
+ default:
178
+ throw new Error(`Unknown accounts operation: ${operation}`);
179
+ }
180
+ }
181
+ //# sourceMappingURL=accounts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accounts.js","sourceRoot":"","sources":["../../../src/server/handlers/accounts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { HandlerResponse } from '../handler.js';
2
+ export declare function handleCalendar(params: Record<string, unknown>): Promise<HandlerResponse>;
@@ -0,0 +1,93 @@
1
+ import { execute } from '../../executor/gws.js';
2
+ import { formatEventList, formatEventDetail } from '../formatting/markdown.js';
3
+ import { nextSteps } from '../formatting/next-steps.js';
4
+ import { requireEmail, requireString, clamp } from './validate.js';
5
+ export async function handleCalendar(params) {
6
+ const operation = params.operation;
7
+ const email = requireEmail(params);
8
+ switch (operation) {
9
+ case 'list': {
10
+ const now = new Date();
11
+ const todayStart = new Date(now.getFullYear(), now.getMonth(), now.getDate()).toISOString();
12
+ const result = await execute([
13
+ 'calendar', 'events', 'list',
14
+ '--params', JSON.stringify({
15
+ calendarId: 'primary',
16
+ timeMin: params.timeMin || todayStart,
17
+ timeMax: params.timeMax || undefined,
18
+ maxResults: clamp(params.maxResults, 10, 50),
19
+ singleEvents: true,
20
+ orderBy: 'startTime',
21
+ }),
22
+ ], { account: email });
23
+ const formatted = formatEventList(result.data);
24
+ return {
25
+ text: formatted.text + nextSteps('calendar', 'list', { email }),
26
+ refs: formatted.refs,
27
+ };
28
+ }
29
+ case 'agenda': {
30
+ const result = await execute(['calendar', '+agenda'], { account: email });
31
+ const data = result.data;
32
+ const text = typeof result.data === 'string' ? result.data : JSON.stringify(result.data, null, 2);
33
+ // Curate refs — only expose fields useful for chaining
34
+ const events = Array.isArray(data?.events) ? data.events : [];
35
+ return {
36
+ text: text + nextSteps('calendar', 'agenda', { email }),
37
+ refs: {
38
+ count: events.length,
39
+ eventId: events[0]?.id,
40
+ events: events.map((e) => e.id),
41
+ },
42
+ };
43
+ }
44
+ case 'create': {
45
+ const summary = requireString(params, 'summary');
46
+ const start = requireString(params, 'start');
47
+ const end = requireString(params, 'end');
48
+ const args = ['calendar', '+insert', '--summary', summary, '--start', start, '--end', end];
49
+ if (params.description)
50
+ args.push('--description', String(params.description));
51
+ if (params.location)
52
+ args.push('--location', String(params.location));
53
+ if (params.attendees)
54
+ args.push('--attendees', String(params.attendees));
55
+ const result = await execute(args, { account: email });
56
+ const data = result.data;
57
+ return {
58
+ text: `Event created: **${summary}**\n\n` +
59
+ `**When:** ${start} – ${end}\n` +
60
+ (params.location ? `**Where:** ${params.location}\n` : '') +
61
+ `**Event ID:** ${data.id ?? 'unknown'}` +
62
+ nextSteps('calendar', 'create', { email }),
63
+ refs: { id: data.id, eventId: data.id, summary, start, end },
64
+ };
65
+ }
66
+ case 'get': {
67
+ const eventId = requireString(params, 'eventId');
68
+ const result = await execute([
69
+ 'calendar', 'events', 'get',
70
+ '--params', JSON.stringify({ calendarId: 'primary', eventId }),
71
+ ], { account: email });
72
+ const formatted = formatEventDetail(result.data);
73
+ return {
74
+ text: formatted.text + nextSteps('calendar', 'get', { email, eventId }),
75
+ refs: formatted.refs,
76
+ };
77
+ }
78
+ case 'delete': {
79
+ const eventId = requireString(params, 'eventId');
80
+ await execute([
81
+ 'calendar', 'events', 'delete',
82
+ '--params', JSON.stringify({ calendarId: 'primary', eventId }),
83
+ ], { account: email });
84
+ return {
85
+ text: `Event deleted: ${eventId}` + nextSteps('calendar', 'delete', { email }),
86
+ refs: { eventId, status: 'deleted' },
87
+ };
88
+ }
89
+ default:
90
+ throw new Error(`Unknown calendar operation: ${operation}`);
91
+ }
92
+ }
93
+ //# sourceMappingURL=calendar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calendar.js","sourceRoot":"","sources":["../../../src/server/handlers/calendar.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { HandlerResponse } from '../handler.js';
2
+ export declare function handleDrive(params: Record<string, unknown>): Promise<HandlerResponse>;
@@ -0,0 +1,74 @@
1
+ import { execute } from '../../executor/gws.js';
2
+ import { formatFileList, formatFileDetail } from '../formatting/markdown.js';
3
+ import { nextSteps } from '../formatting/next-steps.js';
4
+ import { requireEmail, requireString, clamp } from './validate.js';
5
+ export async function handleDrive(params) {
6
+ const operation = params.operation;
7
+ const email = requireEmail(params);
8
+ switch (operation) {
9
+ case 'search': {
10
+ const result = await execute([
11
+ 'drive', 'files', 'list',
12
+ '--params', JSON.stringify({
13
+ q: params.query || undefined,
14
+ pageSize: clamp(params.maxResults, 10, 50),
15
+ fields: 'files(id, name, mimeType, modifiedTime, size, webViewLink)',
16
+ }),
17
+ ], { account: email });
18
+ const formatted = formatFileList(result.data);
19
+ return {
20
+ text: formatted.text + nextSteps('drive', 'search', { email }),
21
+ refs: formatted.refs,
22
+ };
23
+ }
24
+ case 'get': {
25
+ const fileId = requireString(params, 'fileId');
26
+ const result = await execute([
27
+ 'drive', 'files', 'get',
28
+ '--params', JSON.stringify({
29
+ fileId,
30
+ fields: 'id, name, mimeType, modifiedTime, size, webViewLink, owners, shared',
31
+ }),
32
+ ], { account: email });
33
+ const formatted = formatFileDetail(result.data);
34
+ return {
35
+ text: formatted.text + nextSteps('drive', 'get', { email, fileId }),
36
+ refs: formatted.refs,
37
+ };
38
+ }
39
+ case 'upload': {
40
+ const filePath = requireString(params, 'filePath');
41
+ const args = ['drive', '+upload', filePath];
42
+ if (params.name)
43
+ args.push('--name', String(params.name));
44
+ if (params.parentFolderId)
45
+ args.push('--parent', String(params.parentFolderId));
46
+ const result = await execute(args, { account: email });
47
+ const data = result.data;
48
+ return {
49
+ text: `File uploaded: **${data.name ?? filePath}**\n\n**File ID:** ${data.id ?? 'unknown'}` +
50
+ nextSteps('drive', 'upload', { email }),
51
+ refs: { id: data.id, fileId: data.id, name: data.name },
52
+ };
53
+ }
54
+ case 'download': {
55
+ const fileId = requireString(params, 'fileId');
56
+ const args = [
57
+ 'drive', 'files', 'get',
58
+ '--params', JSON.stringify({ fileId, alt: 'media' }),
59
+ ];
60
+ if (params.outputPath)
61
+ args.push('--output', String(params.outputPath));
62
+ await execute(args, { account: email });
63
+ return {
64
+ text: `File downloaded: ${fileId}` +
65
+ (params.outputPath ? ` → ${params.outputPath}` : '') +
66
+ nextSteps('drive', 'download', { email }),
67
+ refs: { fileId, status: 'downloaded' },
68
+ };
69
+ }
70
+ default:
71
+ throw new Error(`Unknown drive operation: ${operation}`);
72
+ }
73
+ }
74
+ //# sourceMappingURL=drive.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drive.js","sourceRoot":"","sources":["../../../src/server/handlers/drive.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { HandlerResponse } from '../handler.js';
2
+ export declare function handleEmail(params: Record<string, unknown>): Promise<HandlerResponse>;
@@ -0,0 +1,115 @@
1
+ import { execute } from '../../executor/gws.js';
2
+ import { formatEmailList, formatEmailDetail } from '../formatting/markdown.js';
3
+ import { nextSteps } from '../formatting/next-steps.js';
4
+ import { requireEmail, requireString, clamp } from './validate.js';
5
+ /**
6
+ * Gmail messages.list only returns IDs. This hydrates each message
7
+ * with metadata (From, Subject, Date, snippet) via parallel gets.
8
+ */
9
+ async function hydrateMessages(messageIds, account) {
10
+ const hydrated = await Promise.all(messageIds.map(async (msg) => {
11
+ try {
12
+ const result = await execute([
13
+ 'gmail', 'users', 'messages', 'get',
14
+ '--params', JSON.stringify({
15
+ userId: 'me',
16
+ id: msg.id,
17
+ format: 'metadata',
18
+ metadataHeaders: ['From', 'Subject', 'Date'],
19
+ }),
20
+ ], { account });
21
+ const data = result.data;
22
+ const headers = (data.payload?.headers ?? []);
23
+ const getHeader = (name) => headers.find(h => h.name.toLowerCase() === name.toLowerCase())?.value;
24
+ return {
25
+ id: data.id,
26
+ threadId: data.threadId,
27
+ from: getHeader('from'),
28
+ subject: getHeader('subject'),
29
+ date: getHeader('date'),
30
+ snippet: data.snippet,
31
+ };
32
+ }
33
+ catch {
34
+ // If individual hydration fails, return the bare ID
35
+ return { id: msg.id };
36
+ }
37
+ }));
38
+ return hydrated;
39
+ }
40
+ export async function handleEmail(params) {
41
+ const operation = params.operation;
42
+ const email = requireEmail(params);
43
+ switch (operation) {
44
+ case 'search': {
45
+ const result = await execute([
46
+ 'gmail', 'users', 'messages', 'list',
47
+ '--params', JSON.stringify({
48
+ userId: 'me',
49
+ q: params.query || '',
50
+ maxResults: clamp(params.maxResults, 10, 50),
51
+ }),
52
+ ], { account: email });
53
+ // messages.list only returns IDs — hydrate with metadata
54
+ const raw = result.data;
55
+ const ids = (raw?.messages ?? []);
56
+ const messages = ids.length > 0 ? await hydrateMessages(ids, email) : [];
57
+ const formatted = formatEmailList({ messages });
58
+ return {
59
+ text: formatted.text + nextSteps('email', 'search', { email }),
60
+ refs: formatted.refs,
61
+ };
62
+ }
63
+ case 'read': {
64
+ const messageId = requireString(params, 'messageId');
65
+ const result = await execute([
66
+ 'gmail', 'users', 'messages', 'get',
67
+ '--params', JSON.stringify({ userId: 'me', id: messageId }),
68
+ ], { account: email });
69
+ const formatted = formatEmailDetail(result.data);
70
+ return {
71
+ text: formatted.text + nextSteps('email', 'read', { email, messageId }),
72
+ refs: formatted.refs,
73
+ };
74
+ }
75
+ case 'send': {
76
+ const to = requireString(params, 'to');
77
+ const subject = requireString(params, 'subject');
78
+ const body = requireString(params, 'body');
79
+ const result = await execute([
80
+ 'gmail', '+send',
81
+ '--to', to, '--subject', subject, '--body', body,
82
+ ], { account: email });
83
+ const data = result.data;
84
+ return {
85
+ text: `Email sent to ${to}.\n\n**Subject:** ${subject}\n**Message ID:** ${data.id ?? 'unknown'}` +
86
+ nextSteps('email', 'send', { email }),
87
+ refs: { id: data.id, threadId: data.threadId, to, subject },
88
+ };
89
+ }
90
+ case 'reply': {
91
+ const messageId = requireString(params, 'messageId');
92
+ const body = requireString(params, 'body');
93
+ const result = await execute([
94
+ 'gmail', '+reply', '--message-id', messageId, '--body', body,
95
+ ], { account: email });
96
+ const data = result.data;
97
+ return {
98
+ text: `Reply sent.\n\n**Message ID:** ${data.id ?? 'unknown'}` +
99
+ nextSteps('email', 'reply', { email }),
100
+ refs: { id: data.id, threadId: data.threadId, messageId },
101
+ };
102
+ }
103
+ case 'triage': {
104
+ const result = await execute(['gmail', '+triage'], { account: email, format: 'json' });
105
+ const formatted = formatEmailList(result.data);
106
+ return {
107
+ text: formatted.text + nextSteps('email', 'triage', { email }),
108
+ refs: formatted.refs,
109
+ };
110
+ }
111
+ default:
112
+ throw new Error(`Unknown email operation: ${operation}`);
113
+ }
114
+ }
115
+ //# sourceMappingURL=email.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email.js","sourceRoot":"","sources":["../../../src/server/handlers/email.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare function requireEmail(params: Record<string, unknown>): string;
2
+ export declare function requireString(params: Record<string, unknown>, field: string): string;
3
+ export declare function clamp(value: unknown, defaultVal: number, max: number): number;
@@ -0,0 +1,22 @@
1
+ const EMAIL_RE = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
2
+ export function requireEmail(params) {
3
+ const email = params.email;
4
+ if (typeof email !== 'string' || !EMAIL_RE.test(email)) {
5
+ throw new Error('A valid email address is required for this operation');
6
+ }
7
+ return email;
8
+ }
9
+ export function requireString(params, field) {
10
+ const value = params[field];
11
+ if (typeof value !== 'string' || value.trim() === '') {
12
+ throw new Error(`${field} is required`);
13
+ }
14
+ return value;
15
+ }
16
+ export function clamp(value, defaultVal, max) {
17
+ const n = Number(value);
18
+ if (Number.isNaN(n) || n <= 0)
19
+ return Math.min(defaultVal, max);
20
+ return Math.min(n, max);
21
+ }
22
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../src/server/handlers/validate.ts"],"names":[],"mappings":"AAAA,MAAM,QAAQ,GAAG,kDAAkD,CAAC;AAEpE,MAAM,UAAU,YAAY,CAAC,MAA+B;IAC1D,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;IAC3B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACvD,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;IAC1E,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAA+B,EAAE,KAAa;IAC1E,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACrD,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,cAAc,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,KAAc,EAAE,UAAkB,EAAE,GAAW;IACnE,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IACxB,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;IAChE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Workspace handler — file CRUD within the sandboxed workspace directory.
3
+ *
4
+ * The workspace is the exchange point between the MCP server and the agent.
5
+ * Files saved by getAttachment, download, and export land here. The agent
6
+ * can also read, write, and manage files directly.
7
+ */
8
+ import type { HandlerResponse } from '../formatting/markdown.js';
9
+ export declare function handleWorkspace(params: Record<string, unknown>): Promise<HandlerResponse>;