gogcli-mcp 2.30.0 → 4.0.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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/dist/index.js +15345 -18417
- package/dist/lib.js +13720 -9481
- package/manifest.json +2 -2
- package/mint.yaml +37 -33
- package/package.json +5 -5
- package/server.json +2 -2
- package/src/attachments.ts +28 -34
- package/src/blob-upload.ts +165 -134
- package/src/blob-urls.ts +3 -5
- package/src/bootstrap-auth.ts +97 -0
- package/src/gmail-dispatch-guard.ts +106 -0
- package/src/gmail-results.ts +1 -1
- package/src/index.ts +3 -4
- package/src/lib.ts +24 -9
- package/src/pagination.ts +1 -1
- package/src/runner.ts +23 -175
- package/src/tools/api.ts +7 -7
- package/src/tools/appscript.ts +16 -16
- package/src/tools/auth.ts +16 -16
- package/src/tools/calendar.ts +13 -13
- package/src/tools/chat.ts +25 -25
- package/src/tools/classroom.ts +49 -49
- package/src/tools/contacts.ts +9 -9
- package/src/tools/docs.ts +13 -13
- package/src/tools/drive.ts +23 -25
- package/src/tools/gmail.ts +145 -32
- package/src/tools/sheets.ts +15 -15
- package/src/tools/slides.ts +13 -13
- package/src/tools/tasks.ts +13 -13
- package/src/tools/utils.ts +14 -61
- package/tests/attachments.test.ts +11 -14
- package/tests/blob-upload.test.ts +235 -160
- package/tests/bootstrap-auth.test.ts +245 -0
- package/tests/gmail-dispatch-guard.test.ts +132 -0
- package/tests/runner-file-args.test.ts +1 -13
- package/tests/runner.test.ts +8 -95
- package/tests/sdk-single-copy.test.ts +11 -37
- package/tests/tools/appscript.test.ts +1 -1
- package/tests/tools/auth-401-shapes.test.ts +2 -3
- package/tests/tools/auth.test.ts +5 -4
- package/tests/tools/chat.test.ts +1 -1
- package/tests/tools/drive.test.ts +11 -3
- package/tests/tools/gmail.test.ts +244 -14
- package/tests/tools/sheets.test.ts +1 -1
- package/tests/tools/utils.test.ts +1 -50
- package/tests/zod-single-copy.test.ts +8 -16
- package/tsconfig.json +1 -4
- package/vitest.config.ts +2 -14
- package/src/auth-log.ts +0 -205
- package/src/connector-auth.ts +0 -303
- package/src/connector-runtime.ts +0 -887
- package/src/google-probe.ts +0 -113
- package/src/google-token.ts +0 -391
- package/src/remote-runner.ts +0 -77
- package/src/worker.ts +0 -129
- package/tests/auth-log.test.ts +0 -530
- package/tests/connector-auth.test.ts +0 -559
- package/tests/connector-runtime.test.ts +0 -1644
- package/tests/google-probe.test.ts +0 -116
- package/tests/google-token.test.ts +0 -425
- package/tests/remote-runner.test.ts +0 -202
- package/tests/worker.test.ts +0 -167
package/src/tools/classroom.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { McpServer } from '@modelcontextprotocol/
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/server';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { accountParam, runOrDiagnose, registerRunTool, pageTokenParam, pageAliasParam, resolvePageToken} from './utils.js';
|
|
4
4
|
|
|
@@ -6,7 +6,7 @@ export function registerClassroomTools(server: McpServer): void {
|
|
|
6
6
|
server.registerTool('gog_classroom_courses_list', {
|
|
7
7
|
description: 'List Google Classroom courses.',
|
|
8
8
|
annotations: { readOnlyHint: true },
|
|
9
|
-
inputSchema: {
|
|
9
|
+
inputSchema: z.object({
|
|
10
10
|
state: z.string().optional().describe('Comma-separated course states (ACTIVE, ARCHIVED, PROVISIONED, DECLINED, SUSPENDED)'),
|
|
11
11
|
teacher: z.string().optional().describe('Filter by teacher user ID'),
|
|
12
12
|
student: z.string().optional().describe('Filter by student user ID'),
|
|
@@ -15,7 +15,7 @@ export function registerClassroomTools(server: McpServer): void {
|
|
|
15
15
|
page: pageAliasParam,
|
|
16
16
|
all: z.boolean().optional().describe('Fetch all pages'),
|
|
17
17
|
account: accountParam,
|
|
18
|
-
},
|
|
18
|
+
}),
|
|
19
19
|
}, async ({ state, teacher, student, max, pageToken, page, all, account }) => {
|
|
20
20
|
const args = ['classroom', 'courses', 'list'];
|
|
21
21
|
if (state) args.push(`--state=${state}`);
|
|
@@ -31,10 +31,10 @@ export function registerClassroomTools(server: McpServer): void {
|
|
|
31
31
|
server.registerTool('gog_classroom_courses_get', {
|
|
32
32
|
description: 'Get a single Google Classroom course by ID.',
|
|
33
33
|
annotations: { readOnlyHint: true },
|
|
34
|
-
inputSchema: {
|
|
34
|
+
inputSchema: z.object({
|
|
35
35
|
courseId: z.string().describe('Course ID'),
|
|
36
36
|
account: accountParam,
|
|
37
|
-
},
|
|
37
|
+
}),
|
|
38
38
|
}, async ({ courseId, account }) => {
|
|
39
39
|
return runOrDiagnose(['classroom', 'courses', 'get', courseId], { account });
|
|
40
40
|
});
|
|
@@ -42,14 +42,14 @@ export function registerClassroomTools(server: McpServer): void {
|
|
|
42
42
|
server.registerTool('gog_classroom_students_list', {
|
|
43
43
|
description: 'List students enrolled in a Google Classroom course.',
|
|
44
44
|
annotations: { readOnlyHint: true },
|
|
45
|
-
inputSchema: {
|
|
45
|
+
inputSchema: z.object({
|
|
46
46
|
courseId: z.string().describe('Course ID'),
|
|
47
47
|
max: z.number().optional().describe('Max results per page'),
|
|
48
48
|
pageToken: pageTokenParam,
|
|
49
49
|
page: pageAliasParam,
|
|
50
50
|
all: z.boolean().optional().describe('Fetch all pages'),
|
|
51
51
|
account: accountParam,
|
|
52
|
-
},
|
|
52
|
+
}),
|
|
53
53
|
}, async ({ courseId, max, pageToken, page, all, account }) => {
|
|
54
54
|
const args = ['classroom', 'students', 'list', courseId];
|
|
55
55
|
if (max !== undefined) args.push(`--max=${max}`);
|
|
@@ -62,11 +62,11 @@ export function registerClassroomTools(server: McpServer): void {
|
|
|
62
62
|
server.registerTool('gog_classroom_students_get', {
|
|
63
63
|
description: 'Get a specific student enrolled in a course.',
|
|
64
64
|
annotations: { readOnlyHint: true },
|
|
65
|
-
inputSchema: {
|
|
65
|
+
inputSchema: z.object({
|
|
66
66
|
courseId: z.string().describe('Course ID'),
|
|
67
67
|
userId: z.string().describe('Student user ID'),
|
|
68
68
|
account: accountParam,
|
|
69
|
-
},
|
|
69
|
+
}),
|
|
70
70
|
}, async ({ courseId, userId, account }) => {
|
|
71
71
|
return runOrDiagnose(['classroom', 'students', 'get', courseId, userId], { account });
|
|
72
72
|
});
|
|
@@ -74,14 +74,14 @@ export function registerClassroomTools(server: McpServer): void {
|
|
|
74
74
|
server.registerTool('gog_classroom_teachers_list', {
|
|
75
75
|
description: 'List teachers in a Google Classroom course.',
|
|
76
76
|
annotations: { readOnlyHint: true },
|
|
77
|
-
inputSchema: {
|
|
77
|
+
inputSchema: z.object({
|
|
78
78
|
courseId: z.string().describe('Course ID'),
|
|
79
79
|
max: z.number().optional().describe('Max results per page'),
|
|
80
80
|
pageToken: pageTokenParam,
|
|
81
81
|
page: pageAliasParam,
|
|
82
82
|
all: z.boolean().optional().describe('Fetch all pages'),
|
|
83
83
|
account: accountParam,
|
|
84
|
-
},
|
|
84
|
+
}),
|
|
85
85
|
}, async ({ courseId, max, pageToken, page, all, account }) => {
|
|
86
86
|
const args = ['classroom', 'teachers', 'list', courseId];
|
|
87
87
|
if (max !== undefined) args.push(`--max=${max}`);
|
|
@@ -94,11 +94,11 @@ export function registerClassroomTools(server: McpServer): void {
|
|
|
94
94
|
server.registerTool('gog_classroom_teachers_get', {
|
|
95
95
|
description: 'Get a specific teacher in a course.',
|
|
96
96
|
annotations: { readOnlyHint: true },
|
|
97
|
-
inputSchema: {
|
|
97
|
+
inputSchema: z.object({
|
|
98
98
|
courseId: z.string().describe('Course ID'),
|
|
99
99
|
userId: z.string().describe('Teacher user ID'),
|
|
100
100
|
account: accountParam,
|
|
101
|
-
},
|
|
101
|
+
}),
|
|
102
102
|
}, async ({ courseId, userId, account }) => {
|
|
103
103
|
return runOrDiagnose(['classroom', 'teachers', 'get', courseId, userId], { account });
|
|
104
104
|
});
|
|
@@ -106,7 +106,7 @@ export function registerClassroomTools(server: McpServer): void {
|
|
|
106
106
|
server.registerTool('gog_classroom_roster', {
|
|
107
107
|
description: 'List the full roster (students and/or teachers) of a Google Classroom course. Omit both flags to return both groups.',
|
|
108
108
|
annotations: { readOnlyHint: true },
|
|
109
|
-
inputSchema: {
|
|
109
|
+
inputSchema: z.object({
|
|
110
110
|
courseId: z.string().describe('Course ID'),
|
|
111
111
|
students: z.boolean().optional().describe('Include students only'),
|
|
112
112
|
teachers: z.boolean().optional().describe('Include teachers only'),
|
|
@@ -115,7 +115,7 @@ export function registerClassroomTools(server: McpServer): void {
|
|
|
115
115
|
page: pageAliasParam,
|
|
116
116
|
all: z.boolean().optional().describe('Fetch all pages'),
|
|
117
117
|
account: accountParam,
|
|
118
|
-
},
|
|
118
|
+
}),
|
|
119
119
|
}, async ({ courseId, students, teachers, max, pageToken, page, all, account }) => {
|
|
120
120
|
const args = ['classroom', 'roster', courseId];
|
|
121
121
|
if (students) args.push('--students');
|
|
@@ -130,7 +130,7 @@ export function registerClassroomTools(server: McpServer): void {
|
|
|
130
130
|
server.registerTool('gog_classroom_coursework_list', {
|
|
131
131
|
description: 'List coursework (assignments, questions, materials) for a course.',
|
|
132
132
|
annotations: { readOnlyHint: true },
|
|
133
|
-
inputSchema: {
|
|
133
|
+
inputSchema: z.object({
|
|
134
134
|
courseId: z.string().describe('Course ID'),
|
|
135
135
|
state: z.string().optional().describe('Filter by coursework state (PUBLISHED, DRAFT, DELETED)'),
|
|
136
136
|
topic: z.string().optional().describe('Filter by topic ID'),
|
|
@@ -141,7 +141,7 @@ export function registerClassroomTools(server: McpServer): void {
|
|
|
141
141
|
all: z.boolean().optional().describe('Fetch all pages'),
|
|
142
142
|
scanPages: z.number().optional().describe('Max pages to scan when filtering'),
|
|
143
143
|
account: accountParam,
|
|
144
|
-
},
|
|
144
|
+
}),
|
|
145
145
|
}, async ({ courseId, state, topic, orderBy, max, pageToken, page, all, scanPages, account }) => {
|
|
146
146
|
const args = ['classroom', 'coursework', 'list', courseId];
|
|
147
147
|
if (state) args.push(`--state=${state}`);
|
|
@@ -158,11 +158,11 @@ export function registerClassroomTools(server: McpServer): void {
|
|
|
158
158
|
server.registerTool('gog_classroom_coursework_get', {
|
|
159
159
|
description: 'Get a single coursework item by ID.',
|
|
160
160
|
annotations: { readOnlyHint: true },
|
|
161
|
-
inputSchema: {
|
|
161
|
+
inputSchema: z.object({
|
|
162
162
|
courseId: z.string().describe('Course ID'),
|
|
163
163
|
courseworkId: z.string().describe('Coursework ID'),
|
|
164
164
|
account: accountParam,
|
|
165
|
-
},
|
|
165
|
+
}),
|
|
166
166
|
}, async ({ courseId, courseworkId, account }) => {
|
|
167
167
|
return runOrDiagnose(['classroom', 'coursework', 'get', courseId, courseworkId], { account });
|
|
168
168
|
});
|
|
@@ -170,7 +170,7 @@ export function registerClassroomTools(server: McpServer): void {
|
|
|
170
170
|
server.registerTool('gog_classroom_submissions_list', {
|
|
171
171
|
description: 'List student submissions for a coursework item.',
|
|
172
172
|
annotations: { readOnlyHint: true },
|
|
173
|
-
inputSchema: {
|
|
173
|
+
inputSchema: z.object({
|
|
174
174
|
courseId: z.string().describe('Course ID'),
|
|
175
175
|
courseworkId: z.string().describe('Coursework ID'),
|
|
176
176
|
state: z.string().optional().describe('Filter by submission state'),
|
|
@@ -181,7 +181,7 @@ export function registerClassroomTools(server: McpServer): void {
|
|
|
181
181
|
page: pageAliasParam,
|
|
182
182
|
all: z.boolean().optional().describe('Fetch all pages'),
|
|
183
183
|
account: accountParam,
|
|
184
|
-
},
|
|
184
|
+
}),
|
|
185
185
|
}, async ({ courseId, courseworkId, state, late, user, max, pageToken, page, all, account }) => {
|
|
186
186
|
const args = ['classroom', 'submissions', 'list', courseId, courseworkId];
|
|
187
187
|
if (state) args.push(`--state=${state}`);
|
|
@@ -197,12 +197,12 @@ export function registerClassroomTools(server: McpServer): void {
|
|
|
197
197
|
server.registerTool('gog_classroom_submissions_get', {
|
|
198
198
|
description: 'Get a single submission by ID.',
|
|
199
199
|
annotations: { readOnlyHint: true },
|
|
200
|
-
inputSchema: {
|
|
200
|
+
inputSchema: z.object({
|
|
201
201
|
courseId: z.string().describe('Course ID'),
|
|
202
202
|
courseworkId: z.string().describe('Coursework ID'),
|
|
203
203
|
submissionId: z.string().describe('Submission ID'),
|
|
204
204
|
account: accountParam,
|
|
205
|
-
},
|
|
205
|
+
}),
|
|
206
206
|
}, async ({ courseId, courseworkId, submissionId, account }) => {
|
|
207
207
|
return runOrDiagnose(['classroom', 'submissions', 'get', courseId, courseworkId, submissionId], { account });
|
|
208
208
|
});
|
|
@@ -210,14 +210,14 @@ export function registerClassroomTools(server: McpServer): void {
|
|
|
210
210
|
server.registerTool('gog_classroom_submissions_grade', {
|
|
211
211
|
description: 'Grade a student submission. Set draft and/or assigned grade values.',
|
|
212
212
|
annotations: { destructiveHint: true },
|
|
213
|
-
inputSchema: {
|
|
213
|
+
inputSchema: z.object({
|
|
214
214
|
courseId: z.string().describe('Course ID'),
|
|
215
215
|
courseworkId: z.string().describe('Coursework ID'),
|
|
216
216
|
submissionId: z.string().describe('Submission ID'),
|
|
217
217
|
draft: z.string().optional().describe('Draft grade value'),
|
|
218
218
|
assigned: z.string().optional().describe('Assigned (final) grade value'),
|
|
219
219
|
account: accountParam,
|
|
220
|
-
},
|
|
220
|
+
}),
|
|
221
221
|
}, async ({ courseId, courseworkId, submissionId, draft, assigned, account }) => {
|
|
222
222
|
const args = ['classroom', 'submissions', 'grade', courseId, courseworkId, submissionId];
|
|
223
223
|
if (draft) args.push(`--draft=${draft}`);
|
|
@@ -228,12 +228,12 @@ export function registerClassroomTools(server: McpServer): void {
|
|
|
228
228
|
server.registerTool('gog_classroom_submissions_return', {
|
|
229
229
|
description: 'Return a graded submission to the student.',
|
|
230
230
|
annotations: { destructiveHint: true },
|
|
231
|
-
inputSchema: {
|
|
231
|
+
inputSchema: z.object({
|
|
232
232
|
courseId: z.string().describe('Course ID'),
|
|
233
233
|
courseworkId: z.string().describe('Coursework ID'),
|
|
234
234
|
submissionId: z.string().describe('Submission ID'),
|
|
235
235
|
account: accountParam,
|
|
236
|
-
},
|
|
236
|
+
}),
|
|
237
237
|
}, async ({ courseId, courseworkId, submissionId, account }) => {
|
|
238
238
|
return runOrDiagnose(['classroom', 'submissions', 'return', courseId, courseworkId, submissionId], { account });
|
|
239
239
|
});
|
|
@@ -241,12 +241,12 @@ export function registerClassroomTools(server: McpServer): void {
|
|
|
241
241
|
server.registerTool('gog_classroom_submissions_turn_in', {
|
|
242
242
|
description: 'Turn in a student submission (student action).',
|
|
243
243
|
annotations: { destructiveHint: true },
|
|
244
|
-
inputSchema: {
|
|
244
|
+
inputSchema: z.object({
|
|
245
245
|
courseId: z.string().describe('Course ID'),
|
|
246
246
|
courseworkId: z.string().describe('Coursework ID'),
|
|
247
247
|
submissionId: z.string().describe('Submission ID'),
|
|
248
248
|
account: accountParam,
|
|
249
|
-
},
|
|
249
|
+
}),
|
|
250
250
|
}, async ({ courseId, courseworkId, submissionId, account }) => {
|
|
251
251
|
return runOrDiagnose(['classroom', 'submissions', 'turn-in', courseId, courseworkId, submissionId], { account });
|
|
252
252
|
});
|
|
@@ -254,12 +254,12 @@ export function registerClassroomTools(server: McpServer): void {
|
|
|
254
254
|
server.registerTool('gog_classroom_submissions_reclaim', {
|
|
255
255
|
description: 'Reclaim a turned-in submission (student action to edit a submission).',
|
|
256
256
|
annotations: { destructiveHint: true },
|
|
257
|
-
inputSchema: {
|
|
257
|
+
inputSchema: z.object({
|
|
258
258
|
courseId: z.string().describe('Course ID'),
|
|
259
259
|
courseworkId: z.string().describe('Coursework ID'),
|
|
260
260
|
submissionId: z.string().describe('Submission ID'),
|
|
261
261
|
account: accountParam,
|
|
262
|
-
},
|
|
262
|
+
}),
|
|
263
263
|
}, async ({ courseId, courseworkId, submissionId, account }) => {
|
|
264
264
|
return runOrDiagnose(['classroom', 'submissions', 'reclaim', courseId, courseworkId, submissionId], { account });
|
|
265
265
|
});
|
|
@@ -267,7 +267,7 @@ export function registerClassroomTools(server: McpServer): void {
|
|
|
267
267
|
server.registerTool('gog_classroom_announcements_list', {
|
|
268
268
|
description: 'List announcements in a Google Classroom course.',
|
|
269
269
|
annotations: { readOnlyHint: true },
|
|
270
|
-
inputSchema: {
|
|
270
|
+
inputSchema: z.object({
|
|
271
271
|
courseId: z.string().describe('Course ID'),
|
|
272
272
|
state: z.string().optional().describe('Filter by announcement state'),
|
|
273
273
|
orderBy: z.string().optional().describe('Sort order'),
|
|
@@ -276,7 +276,7 @@ export function registerClassroomTools(server: McpServer): void {
|
|
|
276
276
|
page: pageAliasParam,
|
|
277
277
|
all: z.boolean().optional().describe('Fetch all pages'),
|
|
278
278
|
account: accountParam,
|
|
279
|
-
},
|
|
279
|
+
}),
|
|
280
280
|
}, async ({ courseId, state, orderBy, max, pageToken, page, all, account }) => {
|
|
281
281
|
const args = ['classroom', 'announcements', 'list', courseId];
|
|
282
282
|
if (state) args.push(`--state=${state}`);
|
|
@@ -291,24 +291,24 @@ export function registerClassroomTools(server: McpServer): void {
|
|
|
291
291
|
server.registerTool('gog_classroom_announcements_get', {
|
|
292
292
|
description: 'Get a single announcement by ID.',
|
|
293
293
|
annotations: { readOnlyHint: true },
|
|
294
|
-
inputSchema: {
|
|
294
|
+
inputSchema: z.object({
|
|
295
295
|
courseId: z.string().describe('Course ID'),
|
|
296
296
|
announcementId: z.string().describe('Announcement ID'),
|
|
297
297
|
account: accountParam,
|
|
298
|
-
},
|
|
298
|
+
}),
|
|
299
299
|
}, async ({ courseId, announcementId, account }) => {
|
|
300
300
|
return runOrDiagnose(['classroom', 'announcements', 'get', courseId, announcementId], { account });
|
|
301
301
|
});
|
|
302
302
|
|
|
303
303
|
server.registerTool('gog_classroom_announcements_create', {
|
|
304
304
|
description: 'Create an announcement in a Google Classroom course.',
|
|
305
|
-
inputSchema: {
|
|
305
|
+
inputSchema: z.object({
|
|
306
306
|
courseId: z.string().describe('Course ID'),
|
|
307
307
|
text: z.string().describe('Announcement text'),
|
|
308
308
|
state: z.enum(['PUBLISHED', 'DRAFT']).optional().describe('State'),
|
|
309
309
|
scheduled: z.string().optional().describe('Scheduled publish time'),
|
|
310
310
|
account: accountParam,
|
|
311
|
-
},
|
|
311
|
+
}),
|
|
312
312
|
}, async ({ courseId, text, state, scheduled, account }) => {
|
|
313
313
|
const args = ['classroom', 'announcements', 'create', courseId, `--text=${text}`];
|
|
314
314
|
if (state) args.push(`--state=${state}`);
|
|
@@ -319,14 +319,14 @@ export function registerClassroomTools(server: McpServer): void {
|
|
|
319
319
|
server.registerTool('gog_classroom_topics_list', {
|
|
320
320
|
description: 'List topics in a Google Classroom course.',
|
|
321
321
|
annotations: { readOnlyHint: true },
|
|
322
|
-
inputSchema: {
|
|
322
|
+
inputSchema: z.object({
|
|
323
323
|
courseId: z.string().describe('Course ID'),
|
|
324
324
|
max: z.number().optional().describe('Max results per page'),
|
|
325
325
|
pageToken: pageTokenParam,
|
|
326
326
|
page: pageAliasParam,
|
|
327
327
|
all: z.boolean().optional().describe('Fetch all pages'),
|
|
328
328
|
account: accountParam,
|
|
329
|
-
},
|
|
329
|
+
}),
|
|
330
330
|
}, async ({ courseId, max, pageToken, page, all, account }) => {
|
|
331
331
|
const args = ['classroom', 'topics', 'list', courseId];
|
|
332
332
|
if (max !== undefined) args.push(`--max=${max}`);
|
|
@@ -339,11 +339,11 @@ export function registerClassroomTools(server: McpServer): void {
|
|
|
339
339
|
server.registerTool('gog_classroom_topics_get', {
|
|
340
340
|
description: 'Get a single topic by ID.',
|
|
341
341
|
annotations: { readOnlyHint: true },
|
|
342
|
-
inputSchema: {
|
|
342
|
+
inputSchema: z.object({
|
|
343
343
|
courseId: z.string().describe('Course ID'),
|
|
344
344
|
topicId: z.string().describe('Topic ID'),
|
|
345
345
|
account: accountParam,
|
|
346
|
-
},
|
|
346
|
+
}),
|
|
347
347
|
}, async ({ courseId, topicId, account }) => {
|
|
348
348
|
return runOrDiagnose(['classroom', 'topics', 'get', courseId, topicId], { account });
|
|
349
349
|
});
|
|
@@ -351,7 +351,7 @@ export function registerClassroomTools(server: McpServer): void {
|
|
|
351
351
|
server.registerTool('gog_classroom_invitations_list', {
|
|
352
352
|
description: 'List Google Classroom invitations.',
|
|
353
353
|
annotations: { readOnlyHint: true },
|
|
354
|
-
inputSchema: {
|
|
354
|
+
inputSchema: z.object({
|
|
355
355
|
course: z.string().optional().describe('Filter by course ID'),
|
|
356
356
|
user: z.string().optional().describe('Filter by user ID'),
|
|
357
357
|
max: z.number().optional().describe('Max results per page'),
|
|
@@ -359,7 +359,7 @@ export function registerClassroomTools(server: McpServer): void {
|
|
|
359
359
|
page: pageAliasParam,
|
|
360
360
|
all: z.boolean().optional().describe('Fetch all pages'),
|
|
361
361
|
account: accountParam,
|
|
362
|
-
},
|
|
362
|
+
}),
|
|
363
363
|
}, async ({ course, user, max, pageToken, page, all, account }) => {
|
|
364
364
|
const args = ['classroom', 'invitations', 'list'];
|
|
365
365
|
if (course) args.push(`--course=${course}`);
|
|
@@ -374,20 +374,20 @@ export function registerClassroomTools(server: McpServer): void {
|
|
|
374
374
|
server.registerTool('gog_classroom_invitations_get', {
|
|
375
375
|
description: 'Get a single invitation by ID.',
|
|
376
376
|
annotations: { readOnlyHint: true },
|
|
377
|
-
inputSchema: {
|
|
377
|
+
inputSchema: z.object({
|
|
378
378
|
invitationId: z.string().describe('Invitation ID'),
|
|
379
379
|
account: accountParam,
|
|
380
|
-
},
|
|
380
|
+
}),
|
|
381
381
|
}, async ({ invitationId, account }) => {
|
|
382
382
|
return runOrDiagnose(['classroom', 'invitations', 'get', invitationId], { account });
|
|
383
383
|
});
|
|
384
384
|
|
|
385
385
|
server.registerTool('gog_classroom_invitations_accept', {
|
|
386
386
|
description: 'Accept a Google Classroom invitation.',
|
|
387
|
-
inputSchema: {
|
|
387
|
+
inputSchema: z.object({
|
|
388
388
|
invitationId: z.string().describe('Invitation ID'),
|
|
389
389
|
account: accountParam,
|
|
390
|
-
},
|
|
390
|
+
}),
|
|
391
391
|
}, async ({ invitationId, account }) => {
|
|
392
392
|
return runOrDiagnose(['classroom', 'invitations', 'accept', invitationId], { account });
|
|
393
393
|
});
|
|
@@ -395,10 +395,10 @@ export function registerClassroomTools(server: McpServer): void {
|
|
|
395
395
|
server.registerTool('gog_classroom_profile_get', {
|
|
396
396
|
description: 'Get a Google Classroom user profile. Omit userId to fetch the authenticated user.',
|
|
397
397
|
annotations: { readOnlyHint: true },
|
|
398
|
-
inputSchema: {
|
|
398
|
+
inputSchema: z.object({
|
|
399
399
|
userId: z.string().optional().describe('User ID (omit for self)'),
|
|
400
400
|
account: accountParam,
|
|
401
|
-
},
|
|
401
|
+
}),
|
|
402
402
|
}, async ({ userId, account }) => {
|
|
403
403
|
const args = ['classroom', 'profile', 'get'];
|
|
404
404
|
if (userId) args.push(userId);
|
package/src/tools/contacts.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { McpServer } from '@modelcontextprotocol/
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/server';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { accountParam, runOrDiagnose, registerRunTool } from './utils.js';
|
|
4
4
|
|
|
@@ -6,10 +6,10 @@ export function registerContactsTools(server: McpServer): void {
|
|
|
6
6
|
server.registerTool('gog_contacts_search', {
|
|
7
7
|
description: 'Search personal Google Contacts by name, email, or phone. For searching the Workspace directory (internal users not in your personal contacts), use gog_people_search from gogcli-mcp-contacts.',
|
|
8
8
|
annotations: { readOnlyHint: true },
|
|
9
|
-
inputSchema: {
|
|
9
|
+
inputSchema: z.object({
|
|
10
10
|
query: z.string().describe('Search query (name, email, or phone)'),
|
|
11
11
|
account: accountParam,
|
|
12
|
-
},
|
|
12
|
+
}),
|
|
13
13
|
}, async ({ query, account }) => {
|
|
14
14
|
return runOrDiagnose(['contacts', 'search', query], { account });
|
|
15
15
|
});
|
|
@@ -17,9 +17,9 @@ export function registerContactsTools(server: McpServer): void {
|
|
|
17
17
|
server.registerTool('gog_contacts_list', {
|
|
18
18
|
description: 'List all Google Contacts.',
|
|
19
19
|
annotations: { readOnlyHint: true },
|
|
20
|
-
inputSchema: {
|
|
20
|
+
inputSchema: z.object({
|
|
21
21
|
account: accountParam,
|
|
22
|
-
},
|
|
22
|
+
}),
|
|
23
23
|
}, async ({ account }) => {
|
|
24
24
|
return runOrDiagnose(['contacts', 'list'], { account });
|
|
25
25
|
});
|
|
@@ -27,10 +27,10 @@ export function registerContactsTools(server: McpServer): void {
|
|
|
27
27
|
server.registerTool('gog_contacts_get', {
|
|
28
28
|
description: 'Get a contact by resource name.',
|
|
29
29
|
annotations: { readOnlyHint: true },
|
|
30
|
-
inputSchema: {
|
|
30
|
+
inputSchema: z.object({
|
|
31
31
|
resourceName: z.string().describe('Contact resource name (e.g. people/c12345)'),
|
|
32
32
|
account: accountParam,
|
|
33
|
-
},
|
|
33
|
+
}),
|
|
34
34
|
}, async ({ resourceName, account }) => {
|
|
35
35
|
return runOrDiagnose(['contacts', 'get', resourceName], { account });
|
|
36
36
|
});
|
|
@@ -38,7 +38,7 @@ export function registerContactsTools(server: McpServer): void {
|
|
|
38
38
|
server.registerTool('gog_contacts_create', {
|
|
39
39
|
description: 'Create a new Google Contact.',
|
|
40
40
|
annotations: { destructiveHint: false },
|
|
41
|
-
inputSchema: {
|
|
41
|
+
inputSchema: z.object({
|
|
42
42
|
givenName: z.string().describe('Given (first) name'),
|
|
43
43
|
familyName: z.string().optional().describe('Family (last) name'),
|
|
44
44
|
email: z.string().optional().describe('Email address'),
|
|
@@ -46,7 +46,7 @@ export function registerContactsTools(server: McpServer): void {
|
|
|
46
46
|
org: z.string().optional().describe('Organization/company name'),
|
|
47
47
|
title: z.string().optional().describe('Job title'),
|
|
48
48
|
account: accountParam,
|
|
49
|
-
},
|
|
49
|
+
}),
|
|
50
50
|
}, async ({ givenName, familyName, email, phone, org, title, account }) => {
|
|
51
51
|
const args = ['contacts', 'create', `--given=${givenName}`];
|
|
52
52
|
if (familyName) args.push(`--family=${familyName}`);
|
package/src/tools/docs.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { McpServer } from '@modelcontextprotocol/
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/server';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { accountParam, runOrDiagnose, registerRunTool } from './utils.js';
|
|
4
4
|
|
|
@@ -6,10 +6,10 @@ export function registerDocsTools(server: McpServer): void {
|
|
|
6
6
|
server.registerTool('gog_docs_info', {
|
|
7
7
|
description: 'Get Google Doc metadata: title, ID, and other properties.',
|
|
8
8
|
annotations: { readOnlyHint: true },
|
|
9
|
-
inputSchema: {
|
|
9
|
+
inputSchema: z.object({
|
|
10
10
|
docId: z.string().describe('Doc ID (from the URL)'),
|
|
11
11
|
account: accountParam,
|
|
12
|
-
},
|
|
12
|
+
}),
|
|
13
13
|
}, async ({ docId, account }) => {
|
|
14
14
|
return runOrDiagnose(['docs', 'info', docId], { account });
|
|
15
15
|
});
|
|
@@ -17,11 +17,11 @@ export function registerDocsTools(server: McpServer): void {
|
|
|
17
17
|
server.registerTool('gog_docs_cat', {
|
|
18
18
|
description: 'Read a Google Doc as plain text.',
|
|
19
19
|
annotations: { readOnlyHint: true },
|
|
20
|
-
inputSchema: {
|
|
20
|
+
inputSchema: z.object({
|
|
21
21
|
docId: z.string().describe('Doc ID (from the URL)'),
|
|
22
22
|
chips: z.boolean().optional().describe('Render Google Docs smart chips (people, dates, rich links) inline in the text output'),
|
|
23
23
|
account: accountParam,
|
|
24
|
-
},
|
|
24
|
+
}),
|
|
25
25
|
}, async ({ docId, chips, account }) => {
|
|
26
26
|
const args = ['docs', 'cat', docId];
|
|
27
27
|
if (chips) args.push('--chips');
|
|
@@ -30,10 +30,10 @@ export function registerDocsTools(server: McpServer): void {
|
|
|
30
30
|
|
|
31
31
|
server.registerTool('gog_docs_create', {
|
|
32
32
|
description: 'Create a new Google Doc. Returns JSON with the new docId and URL.',
|
|
33
|
-
inputSchema: {
|
|
33
|
+
inputSchema: z.object({
|
|
34
34
|
title: z.string().describe('Title for the new document'),
|
|
35
35
|
account: accountParam,
|
|
36
|
-
},
|
|
36
|
+
}),
|
|
37
37
|
}, async ({ title, account }) => {
|
|
38
38
|
return runOrDiagnose(['docs', 'create', title], { account });
|
|
39
39
|
});
|
|
@@ -41,7 +41,7 @@ export function registerDocsTools(server: McpServer): void {
|
|
|
41
41
|
server.registerTool('gog_docs_write', {
|
|
42
42
|
description: 'Write text content to a Google Doc, replacing existing body content by default. Set append=true to add after existing content.',
|
|
43
43
|
annotations: { destructiveHint: true },
|
|
44
|
-
inputSchema: {
|
|
44
|
+
inputSchema: z.object({
|
|
45
45
|
docId: z.string().describe('Doc ID (from the URL)'),
|
|
46
46
|
text: z.string().describe('Text content to write'),
|
|
47
47
|
append: z.boolean().optional().describe('Append to existing content instead of replacing (default: false)'),
|
|
@@ -59,7 +59,7 @@ export function registerDocsTools(server: McpServer): void {
|
|
|
59
59
|
keepWithNext: z.boolean().optional().describe('Keep the paragraph with the next paragraph (true) or clear that setting (false)'),
|
|
60
60
|
batch: z.string().optional().describe('Append this mutation to a persisted batch (from gog_batch_begin in gogcli-mcp-docs) instead of applying it — nothing changes in the doc until the batch is submitted.'),
|
|
61
61
|
account: accountParam,
|
|
62
|
-
},
|
|
62
|
+
}),
|
|
63
63
|
}, async ({ docId, text, append, checkOrphans, bullets, bulletPreset, ordered, noBullets, indentStart, indentEnd, indentFirstLine, spaceAbove, spaceBelow, keepLinesTogether, keepWithNext, batch, account }) => {
|
|
64
64
|
const args = ['docs', 'write', docId, `--text=${text}`];
|
|
65
65
|
if (append) args.push('--append');
|
|
@@ -82,12 +82,12 @@ export function registerDocsTools(server: McpServer): void {
|
|
|
82
82
|
server.registerTool('gog_docs_find_replace', {
|
|
83
83
|
description: 'Find and replace text in a Google Doc.',
|
|
84
84
|
annotations: { destructiveHint: true },
|
|
85
|
-
inputSchema: {
|
|
85
|
+
inputSchema: z.object({
|
|
86
86
|
docId: z.string().describe('Doc ID (from the URL)'),
|
|
87
87
|
find: z.string().describe('Text to find'),
|
|
88
88
|
replace: z.string().describe('Replacement text'),
|
|
89
89
|
account: accountParam,
|
|
90
|
-
},
|
|
90
|
+
}),
|
|
91
91
|
}, async ({ docId, find, replace, account }) => {
|
|
92
92
|
return runOrDiagnose(['docs', 'find-replace', docId, find, replace], { account });
|
|
93
93
|
});
|
|
@@ -95,10 +95,10 @@ export function registerDocsTools(server: McpServer): void {
|
|
|
95
95
|
server.registerTool('gog_docs_structure', {
|
|
96
96
|
description: 'Show a Google Doc\'s structure with numbered paragraphs. Useful for understanding the document layout before making index-based edits.',
|
|
97
97
|
annotations: { readOnlyHint: true },
|
|
98
|
-
inputSchema: {
|
|
98
|
+
inputSchema: z.object({
|
|
99
99
|
docId: z.string().describe('Doc ID (from the URL)'),
|
|
100
100
|
account: accountParam,
|
|
101
|
-
},
|
|
101
|
+
}),
|
|
102
102
|
}, async ({ docId, account }) => {
|
|
103
103
|
return runOrDiagnose(['docs', 'structure', docId], { account });
|
|
104
104
|
});
|