gogcli-mcp-classroom 2.0.4 → 2.0.6
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 +4 -4
- package/.claude-plugin/plugin.json +2 -2
- package/dist/index.js +276 -280
- package/manifest.json +1 -1
- package/package.json +1 -1
- package/server.json +3 -3
- package/src/tools/classroom-extra.ts +300 -2
- package/tests/tools/classroom-extra.test.ts +260 -8
|
@@ -6,16 +6,16 @@
|
|
|
6
6
|
"email": "chris.c.hall@gmail.com"
|
|
7
7
|
},
|
|
8
8
|
"metadata": {
|
|
9
|
-
"description": "Extended Google Classroom for Claude via gogcli
|
|
10
|
-
"version": "2.0.
|
|
9
|
+
"description": "Extended Google Classroom for Claude via gogcli \u2014 auth + full Classroom support (courses, rosters, coursework, submissions, announcements, topics, invitations)",
|
|
10
|
+
"version": "2.0.3"
|
|
11
11
|
},
|
|
12
12
|
"plugins": [
|
|
13
13
|
{
|
|
14
14
|
"name": "gogcli-mcp-classroom",
|
|
15
15
|
"displayName": "gogcli (Classroom)",
|
|
16
16
|
"source": "./",
|
|
17
|
-
"description": "Extended Google Classroom for Claude via gogcli
|
|
18
|
-
"version": "2.0.
|
|
17
|
+
"description": "Extended Google Classroom for Claude via gogcli \u2014 auth + full Classroom support (courses, rosters, coursework, submissions, announcements, topics, invitations)",
|
|
18
|
+
"version": "2.0.3",
|
|
19
19
|
"author": {
|
|
20
20
|
"name": "Chris Hall"
|
|
21
21
|
},
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gogcli-mcp-classroom",
|
|
3
3
|
"displayName": "gogcli (Classroom)",
|
|
4
|
-
"version": "2.0.
|
|
5
|
-
"description": "Extended Google Classroom for Claude via gogcli
|
|
4
|
+
"version": "2.0.3",
|
|
5
|
+
"description": "Extended Google Classroom for Claude via gogcli \u2014 auth + full Classroom support (courses, rosters, coursework, submissions, announcements, topics, invitations)",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Chris Hall",
|
|
8
8
|
"email": "chris.c.hall@gmail.com"
|
package/dist/index.js
CHANGED
|
@@ -31061,83 +31061,6 @@ function registerClassroomTools(server2) {
|
|
|
31061
31061
|
}, async ({ courseId, account }) => {
|
|
31062
31062
|
return runOrDiagnose(["classroom", "courses", "get", courseId], { account });
|
|
31063
31063
|
});
|
|
31064
|
-
server2.registerTool("gog_classroom_courses_create", {
|
|
31065
|
-
description: "Create a new Google Classroom course.",
|
|
31066
|
-
inputSchema: {
|
|
31067
|
-
name: external_exports.string().describe("Course name"),
|
|
31068
|
-
owner: external_exports.string().optional().describe('Owner user ID (default: "me")'),
|
|
31069
|
-
section: external_exports.string().optional().describe("Section"),
|
|
31070
|
-
descriptionHeading: external_exports.string().optional().describe("Description heading"),
|
|
31071
|
-
description: external_exports.string().optional().describe("Description"),
|
|
31072
|
-
room: external_exports.string().optional().describe("Room"),
|
|
31073
|
-
state: external_exports.string().optional().describe("Course state: ACTIVE, ARCHIVED, PROVISIONED, DECLINED, SUSPENDED"),
|
|
31074
|
-
account: accountParam
|
|
31075
|
-
}
|
|
31076
|
-
}, async ({ name, owner, section, descriptionHeading, description, room, state, account }) => {
|
|
31077
|
-
const args = ["classroom", "courses", "create", `--name=${name}`];
|
|
31078
|
-
if (owner) args.push(`--owner=${owner}`);
|
|
31079
|
-
if (section) args.push(`--section=${section}`);
|
|
31080
|
-
if (descriptionHeading) args.push(`--description-heading=${descriptionHeading}`);
|
|
31081
|
-
if (description) args.push(`--description=${description}`);
|
|
31082
|
-
if (room) args.push(`--room=${room}`);
|
|
31083
|
-
if (state) args.push(`--state=${state}`);
|
|
31084
|
-
return runOrDiagnose(args, { account });
|
|
31085
|
-
});
|
|
31086
|
-
server2.registerTool("gog_classroom_courses_update", {
|
|
31087
|
-
description: "Update an existing Google Classroom course.",
|
|
31088
|
-
annotations: { destructiveHint: true },
|
|
31089
|
-
inputSchema: {
|
|
31090
|
-
courseId: external_exports.string().describe("Course ID"),
|
|
31091
|
-
name: external_exports.string().optional().describe("Course name"),
|
|
31092
|
-
owner: external_exports.string().optional().describe("Owner user ID"),
|
|
31093
|
-
section: external_exports.string().optional().describe("Section"),
|
|
31094
|
-
descriptionHeading: external_exports.string().optional().describe("Description heading"),
|
|
31095
|
-
description: external_exports.string().optional().describe("Description"),
|
|
31096
|
-
room: external_exports.string().optional().describe("Room"),
|
|
31097
|
-
state: external_exports.string().optional().describe("Course state: ACTIVE, ARCHIVED, PROVISIONED, DECLINED, SUSPENDED"),
|
|
31098
|
-
account: accountParam
|
|
31099
|
-
}
|
|
31100
|
-
}, async ({ courseId, name, owner, section, descriptionHeading, description, room, state, account }) => {
|
|
31101
|
-
const args = ["classroom", "courses", "update", courseId];
|
|
31102
|
-
if (name) args.push(`--name=${name}`);
|
|
31103
|
-
if (owner) args.push(`--owner=${owner}`);
|
|
31104
|
-
if (section) args.push(`--section=${section}`);
|
|
31105
|
-
if (descriptionHeading) args.push(`--description-heading=${descriptionHeading}`);
|
|
31106
|
-
if (description) args.push(`--description=${description}`);
|
|
31107
|
-
if (room) args.push(`--room=${room}`);
|
|
31108
|
-
if (state) args.push(`--state=${state}`);
|
|
31109
|
-
return runOrDiagnose(args, { account });
|
|
31110
|
-
});
|
|
31111
|
-
server2.registerTool("gog_classroom_courses_delete", {
|
|
31112
|
-
description: "Delete a Google Classroom course.",
|
|
31113
|
-
annotations: { destructiveHint: true },
|
|
31114
|
-
inputSchema: {
|
|
31115
|
-
courseId: external_exports.string().describe("Course ID"),
|
|
31116
|
-
account: accountParam
|
|
31117
|
-
}
|
|
31118
|
-
}, async ({ courseId, account }) => {
|
|
31119
|
-
return runOrDiagnose(["classroom", "courses", "delete", courseId], { account });
|
|
31120
|
-
});
|
|
31121
|
-
server2.registerTool("gog_classroom_courses_archive", {
|
|
31122
|
-
description: "Archive a Google Classroom course.",
|
|
31123
|
-
annotations: { destructiveHint: true },
|
|
31124
|
-
inputSchema: {
|
|
31125
|
-
courseId: external_exports.string().describe("Course ID"),
|
|
31126
|
-
account: accountParam
|
|
31127
|
-
}
|
|
31128
|
-
}, async ({ courseId, account }) => {
|
|
31129
|
-
return runOrDiagnose(["classroom", "courses", "archive", courseId], { account });
|
|
31130
|
-
});
|
|
31131
|
-
server2.registerTool("gog_classroom_courses_unarchive", {
|
|
31132
|
-
description: "Unarchive a Google Classroom course (restore to ACTIVE).",
|
|
31133
|
-
annotations: { destructiveHint: true },
|
|
31134
|
-
inputSchema: {
|
|
31135
|
-
courseId: external_exports.string().describe("Course ID"),
|
|
31136
|
-
account: accountParam
|
|
31137
|
-
}
|
|
31138
|
-
}, async ({ courseId, account }) => {
|
|
31139
|
-
return runOrDiagnose(["classroom", "courses", "unarchive", courseId], { account });
|
|
31140
|
-
});
|
|
31141
31064
|
server2.registerTool("gog_classroom_students_list", {
|
|
31142
31065
|
description: "List students enrolled in a Google Classroom course.",
|
|
31143
31066
|
annotations: { readOnlyHint: true },
|
|
@@ -31166,30 +31089,6 @@ function registerClassroomTools(server2) {
|
|
|
31166
31089
|
}, async ({ courseId, userId, account }) => {
|
|
31167
31090
|
return runOrDiagnose(["classroom", "students", "get", courseId, userId], { account });
|
|
31168
31091
|
});
|
|
31169
|
-
server2.registerTool("gog_classroom_students_add", {
|
|
31170
|
-
description: "Add a student to a Google Classroom course.",
|
|
31171
|
-
inputSchema: {
|
|
31172
|
-
courseId: external_exports.string().describe("Course ID"),
|
|
31173
|
-
userId: external_exports.string().describe('Student user ID (or "me")'),
|
|
31174
|
-
enrollmentCode: external_exports.string().optional().describe("Enrollment code (required if adding self via code)"),
|
|
31175
|
-
account: accountParam
|
|
31176
|
-
}
|
|
31177
|
-
}, async ({ courseId, userId, enrollmentCode, account }) => {
|
|
31178
|
-
const args = ["classroom", "students", "add", courseId, userId];
|
|
31179
|
-
if (enrollmentCode) args.push(`--enrollment-code=${enrollmentCode}`);
|
|
31180
|
-
return runOrDiagnose(args, { account });
|
|
31181
|
-
});
|
|
31182
|
-
server2.registerTool("gog_classroom_students_remove", {
|
|
31183
|
-
description: "Remove a student from a Google Classroom course.",
|
|
31184
|
-
annotations: { destructiveHint: true },
|
|
31185
|
-
inputSchema: {
|
|
31186
|
-
courseId: external_exports.string().describe("Course ID"),
|
|
31187
|
-
userId: external_exports.string().describe("Student user ID"),
|
|
31188
|
-
account: accountParam
|
|
31189
|
-
}
|
|
31190
|
-
}, async ({ courseId, userId, account }) => {
|
|
31191
|
-
return runOrDiagnose(["classroom", "students", "remove", courseId, userId], { account });
|
|
31192
|
-
});
|
|
31193
31092
|
server2.registerTool("gog_classroom_teachers_list", {
|
|
31194
31093
|
description: "List teachers in a Google Classroom course.",
|
|
31195
31094
|
annotations: { readOnlyHint: true },
|
|
@@ -31218,27 +31117,6 @@ function registerClassroomTools(server2) {
|
|
|
31218
31117
|
}, async ({ courseId, userId, account }) => {
|
|
31219
31118
|
return runOrDiagnose(["classroom", "teachers", "get", courseId, userId], { account });
|
|
31220
31119
|
});
|
|
31221
|
-
server2.registerTool("gog_classroom_teachers_add", {
|
|
31222
|
-
description: "Add a teacher to a Google Classroom course.",
|
|
31223
|
-
inputSchema: {
|
|
31224
|
-
courseId: external_exports.string().describe("Course ID"),
|
|
31225
|
-
userId: external_exports.string().describe("Teacher user ID"),
|
|
31226
|
-
account: accountParam
|
|
31227
|
-
}
|
|
31228
|
-
}, async ({ courseId, userId, account }) => {
|
|
31229
|
-
return runOrDiagnose(["classroom", "teachers", "add", courseId, userId], { account });
|
|
31230
|
-
});
|
|
31231
|
-
server2.registerTool("gog_classroom_teachers_remove", {
|
|
31232
|
-
description: "Remove a teacher from a Google Classroom course.",
|
|
31233
|
-
annotations: { destructiveHint: true },
|
|
31234
|
-
inputSchema: {
|
|
31235
|
-
courseId: external_exports.string().describe("Course ID"),
|
|
31236
|
-
userId: external_exports.string().describe("Teacher user ID"),
|
|
31237
|
-
account: accountParam
|
|
31238
|
-
}
|
|
31239
|
-
}, async ({ courseId, userId, account }) => {
|
|
31240
|
-
return runOrDiagnose(["classroom", "teachers", "remove", courseId, userId], { account });
|
|
31241
|
-
});
|
|
31242
31120
|
server2.registerTool("gog_classroom_roster", {
|
|
31243
31121
|
description: "List the full roster (students and/or teachers) of a Google Classroom course. Omit both flags to return both groups.",
|
|
31244
31122
|
annotations: { readOnlyHint: true },
|
|
@@ -31296,78 +31174,6 @@ function registerClassroomTools(server2) {
|
|
|
31296
31174
|
}, async ({ courseId, courseworkId, account }) => {
|
|
31297
31175
|
return runOrDiagnose(["classroom", "coursework", "get", courseId, courseworkId], { account });
|
|
31298
31176
|
});
|
|
31299
|
-
server2.registerTool("gog_classroom_coursework_create", {
|
|
31300
|
-
description: "Create a new coursework item (assignment, question, etc.) in a course.",
|
|
31301
|
-
inputSchema: {
|
|
31302
|
-
courseId: external_exports.string().describe("Course ID"),
|
|
31303
|
-
title: external_exports.string().describe("Coursework title"),
|
|
31304
|
-
description: external_exports.string().optional().describe("Description"),
|
|
31305
|
-
type: external_exports.string().optional().describe("Work type (ASSIGNMENT, SHORT_ANSWER_QUESTION, MULTIPLE_CHOICE_QUESTION). Default: ASSIGNMENT"),
|
|
31306
|
-
state: external_exports.string().optional().describe("State: PUBLISHED or DRAFT"),
|
|
31307
|
-
maxPoints: external_exports.number().optional().describe("Max points"),
|
|
31308
|
-
due: external_exports.string().optional().describe("Due datetime (combined date+time)"),
|
|
31309
|
-
dueDate: external_exports.string().optional().describe("Due date (YYYY-MM-DD)"),
|
|
31310
|
-
dueTime: external_exports.string().optional().describe("Due time (HH:MM)"),
|
|
31311
|
-
scheduled: external_exports.string().optional().describe("Scheduled publish time"),
|
|
31312
|
-
topic: external_exports.string().optional().describe("Topic ID"),
|
|
31313
|
-
account: accountParam
|
|
31314
|
-
}
|
|
31315
|
-
}, async ({ courseId, title, description, type, state, maxPoints, due, dueDate, dueTime, scheduled, topic, account }) => {
|
|
31316
|
-
const args = ["classroom", "coursework", "create", courseId, `--title=${title}`];
|
|
31317
|
-
if (description) args.push(`--description=${description}`);
|
|
31318
|
-
if (type) args.push(`--type=${type}`);
|
|
31319
|
-
if (state) args.push(`--state=${state}`);
|
|
31320
|
-
if (maxPoints !== void 0) args.push(`--max-points=${maxPoints}`);
|
|
31321
|
-
if (due) args.push(`--due=${due}`);
|
|
31322
|
-
if (dueDate) args.push(`--due-date=${dueDate}`);
|
|
31323
|
-
if (dueTime) args.push(`--due-time=${dueTime}`);
|
|
31324
|
-
if (scheduled) args.push(`--scheduled=${scheduled}`);
|
|
31325
|
-
if (topic) args.push(`--topic=${topic}`);
|
|
31326
|
-
return runOrDiagnose(args, { account });
|
|
31327
|
-
});
|
|
31328
|
-
server2.registerTool("gog_classroom_coursework_update", {
|
|
31329
|
-
description: "Update an existing coursework item.",
|
|
31330
|
-
annotations: { destructiveHint: true },
|
|
31331
|
-
inputSchema: {
|
|
31332
|
-
courseId: external_exports.string().describe("Course ID"),
|
|
31333
|
-
courseworkId: external_exports.string().describe("Coursework ID"),
|
|
31334
|
-
title: external_exports.string().optional().describe("New title"),
|
|
31335
|
-
description: external_exports.string().optional().describe("New description"),
|
|
31336
|
-
type: external_exports.string().optional().describe("Work type"),
|
|
31337
|
-
state: external_exports.string().optional().describe("State: PUBLISHED or DRAFT"),
|
|
31338
|
-
maxPoints: external_exports.number().optional().describe("Max points"),
|
|
31339
|
-
due: external_exports.string().optional().describe("Due datetime"),
|
|
31340
|
-
dueDate: external_exports.string().optional().describe("Due date (YYYY-MM-DD)"),
|
|
31341
|
-
dueTime: external_exports.string().optional().describe("Due time (HH:MM)"),
|
|
31342
|
-
scheduled: external_exports.string().optional().describe("Scheduled publish time"),
|
|
31343
|
-
topic: external_exports.string().optional().describe("Topic ID"),
|
|
31344
|
-
account: accountParam
|
|
31345
|
-
}
|
|
31346
|
-
}, async ({ courseId, courseworkId, title, description, type, state, maxPoints, due, dueDate, dueTime, scheduled, topic, account }) => {
|
|
31347
|
-
const args = ["classroom", "coursework", "update", courseId, courseworkId];
|
|
31348
|
-
if (title) args.push(`--title=${title}`);
|
|
31349
|
-
if (description) args.push(`--description=${description}`);
|
|
31350
|
-
if (type) args.push(`--type=${type}`);
|
|
31351
|
-
if (state) args.push(`--state=${state}`);
|
|
31352
|
-
if (maxPoints !== void 0) args.push(`--max-points=${maxPoints}`);
|
|
31353
|
-
if (due) args.push(`--due=${due}`);
|
|
31354
|
-
if (dueDate) args.push(`--due-date=${dueDate}`);
|
|
31355
|
-
if (dueTime) args.push(`--due-time=${dueTime}`);
|
|
31356
|
-
if (scheduled) args.push(`--scheduled=${scheduled}`);
|
|
31357
|
-
if (topic) args.push(`--topic=${topic}`);
|
|
31358
|
-
return runOrDiagnose(args, { account });
|
|
31359
|
-
});
|
|
31360
|
-
server2.registerTool("gog_classroom_coursework_delete", {
|
|
31361
|
-
description: "Delete a coursework item.",
|
|
31362
|
-
annotations: { destructiveHint: true },
|
|
31363
|
-
inputSchema: {
|
|
31364
|
-
courseId: external_exports.string().describe("Course ID"),
|
|
31365
|
-
courseworkId: external_exports.string().describe("Coursework ID"),
|
|
31366
|
-
account: accountParam
|
|
31367
|
-
}
|
|
31368
|
-
}, async ({ courseId, courseworkId, account }) => {
|
|
31369
|
-
return runOrDiagnose(["classroom", "coursework", "delete", courseId, courseworkId], { account });
|
|
31370
|
-
});
|
|
31371
31177
|
server2.registerTool("gog_classroom_submissions_list", {
|
|
31372
31178
|
description: "List student submissions for a coursework item.",
|
|
31373
31179
|
annotations: { readOnlyHint: true },
|
|
@@ -31494,7 +31300,7 @@ function registerClassroomTools(server2) {
|
|
|
31494
31300
|
inputSchema: {
|
|
31495
31301
|
courseId: external_exports.string().describe("Course ID"),
|
|
31496
31302
|
text: external_exports.string().describe("Announcement text"),
|
|
31497
|
-
state: external_exports.
|
|
31303
|
+
state: external_exports.enum(["PUBLISHED", "DRAFT"]).optional().describe("State"),
|
|
31498
31304
|
scheduled: external_exports.string().optional().describe("Scheduled publish time"),
|
|
31499
31305
|
account: accountParam
|
|
31500
31306
|
}
|
|
@@ -31504,35 +31310,6 @@ function registerClassroomTools(server2) {
|
|
|
31504
31310
|
if (scheduled) args.push(`--scheduled=${scheduled}`);
|
|
31505
31311
|
return runOrDiagnose(args, { account });
|
|
31506
31312
|
});
|
|
31507
|
-
server2.registerTool("gog_classroom_announcements_update", {
|
|
31508
|
-
description: "Update an existing announcement.",
|
|
31509
|
-
annotations: { destructiveHint: true },
|
|
31510
|
-
inputSchema: {
|
|
31511
|
-
courseId: external_exports.string().describe("Course ID"),
|
|
31512
|
-
announcementId: external_exports.string().describe("Announcement ID"),
|
|
31513
|
-
text: external_exports.string().optional().describe("New text"),
|
|
31514
|
-
state: external_exports.string().optional().describe("State: PUBLISHED or DRAFT"),
|
|
31515
|
-
scheduled: external_exports.string().optional().describe("Scheduled publish time"),
|
|
31516
|
-
account: accountParam
|
|
31517
|
-
}
|
|
31518
|
-
}, async ({ courseId, announcementId, text, state, scheduled, account }) => {
|
|
31519
|
-
const args = ["classroom", "announcements", "update", courseId, announcementId];
|
|
31520
|
-
if (text) args.push(`--text=${text}`);
|
|
31521
|
-
if (state) args.push(`--state=${state}`);
|
|
31522
|
-
if (scheduled) args.push(`--scheduled=${scheduled}`);
|
|
31523
|
-
return runOrDiagnose(args, { account });
|
|
31524
|
-
});
|
|
31525
|
-
server2.registerTool("gog_classroom_announcements_delete", {
|
|
31526
|
-
description: "Delete an announcement.",
|
|
31527
|
-
annotations: { destructiveHint: true },
|
|
31528
|
-
inputSchema: {
|
|
31529
|
-
courseId: external_exports.string().describe("Course ID"),
|
|
31530
|
-
announcementId: external_exports.string().describe("Announcement ID"),
|
|
31531
|
-
account: accountParam
|
|
31532
|
-
}
|
|
31533
|
-
}, async ({ courseId, announcementId, account }) => {
|
|
31534
|
-
return runOrDiagnose(["classroom", "announcements", "delete", courseId, announcementId], { account });
|
|
31535
|
-
});
|
|
31536
31313
|
server2.registerTool("gog_classroom_topics_list", {
|
|
31537
31314
|
description: "List topics in a Google Classroom course.",
|
|
31538
31315
|
annotations: { readOnlyHint: true },
|
|
@@ -31561,39 +31338,6 @@ function registerClassroomTools(server2) {
|
|
|
31561
31338
|
}, async ({ courseId, topicId, account }) => {
|
|
31562
31339
|
return runOrDiagnose(["classroom", "topics", "get", courseId, topicId], { account });
|
|
31563
31340
|
});
|
|
31564
|
-
server2.registerTool("gog_classroom_topics_create", {
|
|
31565
|
-
description: "Create a topic in a Google Classroom course.",
|
|
31566
|
-
inputSchema: {
|
|
31567
|
-
courseId: external_exports.string().describe("Course ID"),
|
|
31568
|
-
name: external_exports.string().describe("Topic name"),
|
|
31569
|
-
account: accountParam
|
|
31570
|
-
}
|
|
31571
|
-
}, async ({ courseId, name, account }) => {
|
|
31572
|
-
return runOrDiagnose(["classroom", "topics", "create", courseId, `--name=${name}`], { account });
|
|
31573
|
-
});
|
|
31574
|
-
server2.registerTool("gog_classroom_topics_update", {
|
|
31575
|
-
description: "Rename an existing topic.",
|
|
31576
|
-
annotations: { destructiveHint: true },
|
|
31577
|
-
inputSchema: {
|
|
31578
|
-
courseId: external_exports.string().describe("Course ID"),
|
|
31579
|
-
topicId: external_exports.string().describe("Topic ID"),
|
|
31580
|
-
name: external_exports.string().describe("New topic name"),
|
|
31581
|
-
account: accountParam
|
|
31582
|
-
}
|
|
31583
|
-
}, async ({ courseId, topicId, name, account }) => {
|
|
31584
|
-
return runOrDiagnose(["classroom", "topics", "update", courseId, topicId, `--name=${name}`], { account });
|
|
31585
|
-
});
|
|
31586
|
-
server2.registerTool("gog_classroom_topics_delete", {
|
|
31587
|
-
description: "Delete a topic.",
|
|
31588
|
-
annotations: { destructiveHint: true },
|
|
31589
|
-
inputSchema: {
|
|
31590
|
-
courseId: external_exports.string().describe("Course ID"),
|
|
31591
|
-
topicId: external_exports.string().describe("Topic ID"),
|
|
31592
|
-
account: accountParam
|
|
31593
|
-
}
|
|
31594
|
-
}, async ({ courseId, topicId, account }) => {
|
|
31595
|
-
return runOrDiagnose(["classroom", "topics", "delete", courseId, topicId], { account });
|
|
31596
|
-
});
|
|
31597
31341
|
server2.registerTool("gog_classroom_invitations_list", {
|
|
31598
31342
|
description: "List Google Classroom invitations.",
|
|
31599
31343
|
annotations: { readOnlyHint: true },
|
|
@@ -31624,17 +31368,6 @@ function registerClassroomTools(server2) {
|
|
|
31624
31368
|
}, async ({ invitationId, account }) => {
|
|
31625
31369
|
return runOrDiagnose(["classroom", "invitations", "get", invitationId], { account });
|
|
31626
31370
|
});
|
|
31627
|
-
server2.registerTool("gog_classroom_invitations_create", {
|
|
31628
|
-
description: "Create an invitation to a Google Classroom course.",
|
|
31629
|
-
inputSchema: {
|
|
31630
|
-
courseId: external_exports.string().describe("Course ID"),
|
|
31631
|
-
userId: external_exports.string().describe("User ID to invite"),
|
|
31632
|
-
role: external_exports.enum(["STUDENT", "TEACHER", "OWNER"]).describe("Role for the invited user"),
|
|
31633
|
-
account: accountParam
|
|
31634
|
-
}
|
|
31635
|
-
}, async ({ courseId, userId, role, account }) => {
|
|
31636
|
-
return runOrDiagnose(["classroom", "invitations", "create", courseId, userId, `--role=${role}`], { account });
|
|
31637
|
-
});
|
|
31638
31371
|
server2.registerTool("gog_classroom_invitations_accept", {
|
|
31639
31372
|
description: "Accept a Google Classroom invitation.",
|
|
31640
31373
|
inputSchema: {
|
|
@@ -31644,16 +31377,6 @@ function registerClassroomTools(server2) {
|
|
|
31644
31377
|
}, async ({ invitationId, account }) => {
|
|
31645
31378
|
return runOrDiagnose(["classroom", "invitations", "accept", invitationId], { account });
|
|
31646
31379
|
});
|
|
31647
|
-
server2.registerTool("gog_classroom_invitations_delete", {
|
|
31648
|
-
description: "Delete (revoke) a Google Classroom invitation.",
|
|
31649
|
-
annotations: { destructiveHint: true },
|
|
31650
|
-
inputSchema: {
|
|
31651
|
-
invitationId: external_exports.string().describe("Invitation ID"),
|
|
31652
|
-
account: accountParam
|
|
31653
|
-
}
|
|
31654
|
-
}, async ({ invitationId, account }) => {
|
|
31655
|
-
return runOrDiagnose(["classroom", "invitations", "delete", invitationId], { account });
|
|
31656
|
-
});
|
|
31657
31380
|
server2.registerTool("gog_classroom_profile_get", {
|
|
31658
31381
|
description: "Get a Google Classroom user profile. Omit userId to fetch the authenticated user.",
|
|
31659
31382
|
annotations: { readOnlyHint: true },
|
|
@@ -31668,6 +31391,7 @@ function registerClassroomTools(server2) {
|
|
|
31668
31391
|
});
|
|
31669
31392
|
server2.registerTool("gog_classroom_run", {
|
|
31670
31393
|
description: "Run any gog classroom subcommand not covered by the other tools (guardians, guardian-invitations, materials, coursework assignees, announcement assignees, etc.). Run `gog classroom --help` for the full list, or `gog classroom <subcommand> --help` for flags.",
|
|
31394
|
+
annotations: { destructiveHint: true },
|
|
31671
31395
|
inputSchema: {
|
|
31672
31396
|
subcommand: external_exports.string().describe('The gog classroom subcommand to run, e.g. "guardians", "materials", "guardian-invitations"'),
|
|
31673
31397
|
args: external_exports.array(external_exports.string()).describe("Additional positional args and flags"),
|
|
@@ -31679,7 +31403,7 @@ function registerClassroomTools(server2) {
|
|
|
31679
31403
|
}
|
|
31680
31404
|
|
|
31681
31405
|
// ../gogcli-mcp/src/server.ts
|
|
31682
|
-
var VERSION = true ? "2.0.
|
|
31406
|
+
var VERSION = true ? "2.0.5" : "0.0.0";
|
|
31683
31407
|
function createServer(options) {
|
|
31684
31408
|
return new McpServer({
|
|
31685
31409
|
name: options?.name ?? "gogcli",
|
|
@@ -31688,7 +31412,279 @@ function createServer(options) {
|
|
|
31688
31412
|
}
|
|
31689
31413
|
|
|
31690
31414
|
// src/tools/classroom-extra.ts
|
|
31691
|
-
|
|
31415
|
+
var courseState = external_exports.enum(["ACTIVE", "ARCHIVED", "PROVISIONED", "DECLINED", "SUSPENDED"]);
|
|
31416
|
+
var workState = external_exports.enum(["PUBLISHED", "DRAFT"]);
|
|
31417
|
+
var workType = external_exports.enum(["ASSIGNMENT", "SHORT_ANSWER_QUESTION", "MULTIPLE_CHOICE_QUESTION"]);
|
|
31418
|
+
var courseSharedFields = {
|
|
31419
|
+
owner: external_exports.string().optional().describe('Owner user ID (default "me" on create)'),
|
|
31420
|
+
section: external_exports.string().optional().describe("Section"),
|
|
31421
|
+
descriptionHeading: external_exports.string().optional().describe("Description heading"),
|
|
31422
|
+
description: external_exports.string().optional().describe("Description"),
|
|
31423
|
+
room: external_exports.string().optional().describe("Room"),
|
|
31424
|
+
state: courseState.optional().describe("Course state")
|
|
31425
|
+
};
|
|
31426
|
+
var courseworkSharedFields = {
|
|
31427
|
+
description: external_exports.string().optional().describe("Description"),
|
|
31428
|
+
type: workType.optional().describe("Work type (default: ASSIGNMENT)"),
|
|
31429
|
+
state: workState.optional().describe("State"),
|
|
31430
|
+
maxPoints: external_exports.number().optional().describe("Max points"),
|
|
31431
|
+
due: external_exports.string().optional().describe("Due datetime (combined date+time)"),
|
|
31432
|
+
dueDate: external_exports.string().optional().describe("Due date (YYYY-MM-DD)"),
|
|
31433
|
+
dueTime: external_exports.string().optional().describe("Due time (HH:MM)"),
|
|
31434
|
+
scheduled: external_exports.string().optional().describe("Scheduled publish time"),
|
|
31435
|
+
topic: external_exports.string().optional().describe("Topic ID")
|
|
31436
|
+
};
|
|
31437
|
+
function registerExtraClassroomTools(server2) {
|
|
31438
|
+
server2.registerTool("gog_classroom_courses_create", {
|
|
31439
|
+
description: "Create a new Google Classroom course.",
|
|
31440
|
+
inputSchema: {
|
|
31441
|
+
name: external_exports.string().describe("Course name"),
|
|
31442
|
+
...courseSharedFields,
|
|
31443
|
+
account: accountParam
|
|
31444
|
+
}
|
|
31445
|
+
}, async ({ name, owner, section, descriptionHeading, description, room, state, account }) => {
|
|
31446
|
+
const args = ["classroom", "courses", "create", `--name=${name}`];
|
|
31447
|
+
if (owner) args.push(`--owner=${owner}`);
|
|
31448
|
+
if (section) args.push(`--section=${section}`);
|
|
31449
|
+
if (descriptionHeading) args.push(`--description-heading=${descriptionHeading}`);
|
|
31450
|
+
if (description) args.push(`--description=${description}`);
|
|
31451
|
+
if (room) args.push(`--room=${room}`);
|
|
31452
|
+
if (state) args.push(`--state=${state}`);
|
|
31453
|
+
return runOrDiagnose(args, { account });
|
|
31454
|
+
});
|
|
31455
|
+
server2.registerTool("gog_classroom_courses_update", {
|
|
31456
|
+
description: "Update an existing Google Classroom course.",
|
|
31457
|
+
annotations: { destructiveHint: true },
|
|
31458
|
+
inputSchema: {
|
|
31459
|
+
courseId: external_exports.string().describe("Course ID"),
|
|
31460
|
+
name: external_exports.string().optional().describe("Course name"),
|
|
31461
|
+
...courseSharedFields,
|
|
31462
|
+
account: accountParam
|
|
31463
|
+
}
|
|
31464
|
+
}, async ({ courseId, name, owner, section, descriptionHeading, description, room, state, account }) => {
|
|
31465
|
+
const args = ["classroom", "courses", "update", courseId];
|
|
31466
|
+
if (name) args.push(`--name=${name}`);
|
|
31467
|
+
if (owner) args.push(`--owner=${owner}`);
|
|
31468
|
+
if (section) args.push(`--section=${section}`);
|
|
31469
|
+
if (descriptionHeading) args.push(`--description-heading=${descriptionHeading}`);
|
|
31470
|
+
if (description) args.push(`--description=${description}`);
|
|
31471
|
+
if (room) args.push(`--room=${room}`);
|
|
31472
|
+
if (state) args.push(`--state=${state}`);
|
|
31473
|
+
return runOrDiagnose(args, { account });
|
|
31474
|
+
});
|
|
31475
|
+
server2.registerTool("gog_classroom_courses_delete", {
|
|
31476
|
+
description: "Delete a Google Classroom course.",
|
|
31477
|
+
annotations: { destructiveHint: true },
|
|
31478
|
+
inputSchema: {
|
|
31479
|
+
courseId: external_exports.string().describe("Course ID"),
|
|
31480
|
+
account: accountParam
|
|
31481
|
+
}
|
|
31482
|
+
}, async ({ courseId, account }) => {
|
|
31483
|
+
return runOrDiagnose(["classroom", "courses", "delete", courseId], { account });
|
|
31484
|
+
});
|
|
31485
|
+
server2.registerTool("gog_classroom_courses_archive", {
|
|
31486
|
+
description: "Archive a Google Classroom course.",
|
|
31487
|
+
annotations: { destructiveHint: true },
|
|
31488
|
+
inputSchema: {
|
|
31489
|
+
courseId: external_exports.string().describe("Course ID"),
|
|
31490
|
+
account: accountParam
|
|
31491
|
+
}
|
|
31492
|
+
}, async ({ courseId, account }) => {
|
|
31493
|
+
return runOrDiagnose(["classroom", "courses", "archive", courseId], { account });
|
|
31494
|
+
});
|
|
31495
|
+
server2.registerTool("gog_classroom_courses_unarchive", {
|
|
31496
|
+
description: "Unarchive a Google Classroom course (restore to ACTIVE).",
|
|
31497
|
+
inputSchema: {
|
|
31498
|
+
courseId: external_exports.string().describe("Course ID"),
|
|
31499
|
+
account: accountParam
|
|
31500
|
+
}
|
|
31501
|
+
}, async ({ courseId, account }) => {
|
|
31502
|
+
return runOrDiagnose(["classroom", "courses", "unarchive", courseId], { account });
|
|
31503
|
+
});
|
|
31504
|
+
server2.registerTool("gog_classroom_students_add", {
|
|
31505
|
+
description: "Add a student to a Google Classroom course.",
|
|
31506
|
+
inputSchema: {
|
|
31507
|
+
courseId: external_exports.string().describe("Course ID"),
|
|
31508
|
+
userId: external_exports.string().describe('Student user ID (or "me")'),
|
|
31509
|
+
enrollmentCode: external_exports.string().optional().describe("Enrollment code (required if adding self via code)"),
|
|
31510
|
+
account: accountParam
|
|
31511
|
+
}
|
|
31512
|
+
}, async ({ courseId, userId, enrollmentCode, account }) => {
|
|
31513
|
+
const args = ["classroom", "students", "add", courseId, userId];
|
|
31514
|
+
if (enrollmentCode) args.push(`--enrollment-code=${enrollmentCode}`);
|
|
31515
|
+
return runOrDiagnose(args, { account });
|
|
31516
|
+
});
|
|
31517
|
+
server2.registerTool("gog_classroom_students_remove", {
|
|
31518
|
+
description: "Remove a student from a Google Classroom course.",
|
|
31519
|
+
annotations: { destructiveHint: true },
|
|
31520
|
+
inputSchema: {
|
|
31521
|
+
courseId: external_exports.string().describe("Course ID"),
|
|
31522
|
+
userId: external_exports.string().describe("Student user ID"),
|
|
31523
|
+
account: accountParam
|
|
31524
|
+
}
|
|
31525
|
+
}, async ({ courseId, userId, account }) => {
|
|
31526
|
+
return runOrDiagnose(["classroom", "students", "remove", courseId, userId], { account });
|
|
31527
|
+
});
|
|
31528
|
+
server2.registerTool("gog_classroom_teachers_add", {
|
|
31529
|
+
description: "Add a teacher to a Google Classroom course.",
|
|
31530
|
+
inputSchema: {
|
|
31531
|
+
courseId: external_exports.string().describe("Course ID"),
|
|
31532
|
+
userId: external_exports.string().describe("Teacher user ID"),
|
|
31533
|
+
account: accountParam
|
|
31534
|
+
}
|
|
31535
|
+
}, async ({ courseId, userId, account }) => {
|
|
31536
|
+
return runOrDiagnose(["classroom", "teachers", "add", courseId, userId], { account });
|
|
31537
|
+
});
|
|
31538
|
+
server2.registerTool("gog_classroom_teachers_remove", {
|
|
31539
|
+
description: "Remove a teacher from a Google Classroom course.",
|
|
31540
|
+
annotations: { destructiveHint: true },
|
|
31541
|
+
inputSchema: {
|
|
31542
|
+
courseId: external_exports.string().describe("Course ID"),
|
|
31543
|
+
userId: external_exports.string().describe("Teacher user ID"),
|
|
31544
|
+
account: accountParam
|
|
31545
|
+
}
|
|
31546
|
+
}, async ({ courseId, userId, account }) => {
|
|
31547
|
+
return runOrDiagnose(["classroom", "teachers", "remove", courseId, userId], { account });
|
|
31548
|
+
});
|
|
31549
|
+
server2.registerTool("gog_classroom_coursework_create", {
|
|
31550
|
+
description: "Create a new coursework item (assignment, question, etc.) in a course.",
|
|
31551
|
+
inputSchema: {
|
|
31552
|
+
courseId: external_exports.string().describe("Course ID"),
|
|
31553
|
+
title: external_exports.string().describe("Coursework title"),
|
|
31554
|
+
...courseworkSharedFields,
|
|
31555
|
+
account: accountParam
|
|
31556
|
+
}
|
|
31557
|
+
}, async ({ courseId, title, description, type, state, maxPoints, due, dueDate, dueTime, scheduled, topic, account }) => {
|
|
31558
|
+
const args = ["classroom", "coursework", "create", courseId, `--title=${title}`];
|
|
31559
|
+
if (description) args.push(`--description=${description}`);
|
|
31560
|
+
if (type) args.push(`--type=${type}`);
|
|
31561
|
+
if (state) args.push(`--state=${state}`);
|
|
31562
|
+
if (maxPoints !== void 0) args.push(`--max-points=${maxPoints}`);
|
|
31563
|
+
if (due) args.push(`--due=${due}`);
|
|
31564
|
+
if (dueDate) args.push(`--due-date=${dueDate}`);
|
|
31565
|
+
if (dueTime) args.push(`--due-time=${dueTime}`);
|
|
31566
|
+
if (scheduled) args.push(`--scheduled=${scheduled}`);
|
|
31567
|
+
if (topic) args.push(`--topic=${topic}`);
|
|
31568
|
+
return runOrDiagnose(args, { account });
|
|
31569
|
+
});
|
|
31570
|
+
server2.registerTool("gog_classroom_coursework_update", {
|
|
31571
|
+
description: "Update an existing coursework item.",
|
|
31572
|
+
annotations: { destructiveHint: true },
|
|
31573
|
+
inputSchema: {
|
|
31574
|
+
courseId: external_exports.string().describe("Course ID"),
|
|
31575
|
+
courseworkId: external_exports.string().describe("Coursework ID"),
|
|
31576
|
+
title: external_exports.string().optional().describe("New title"),
|
|
31577
|
+
...courseworkSharedFields,
|
|
31578
|
+
account: accountParam
|
|
31579
|
+
}
|
|
31580
|
+
}, async ({ courseId, courseworkId, title, description, type, state, maxPoints, due, dueDate, dueTime, scheduled, topic, account }) => {
|
|
31581
|
+
const args = ["classroom", "coursework", "update", courseId, courseworkId];
|
|
31582
|
+
if (title) args.push(`--title=${title}`);
|
|
31583
|
+
if (description) args.push(`--description=${description}`);
|
|
31584
|
+
if (type) args.push(`--type=${type}`);
|
|
31585
|
+
if (state) args.push(`--state=${state}`);
|
|
31586
|
+
if (maxPoints !== void 0) args.push(`--max-points=${maxPoints}`);
|
|
31587
|
+
if (due) args.push(`--due=${due}`);
|
|
31588
|
+
if (dueDate) args.push(`--due-date=${dueDate}`);
|
|
31589
|
+
if (dueTime) args.push(`--due-time=${dueTime}`);
|
|
31590
|
+
if (scheduled) args.push(`--scheduled=${scheduled}`);
|
|
31591
|
+
if (topic) args.push(`--topic=${topic}`);
|
|
31592
|
+
return runOrDiagnose(args, { account });
|
|
31593
|
+
});
|
|
31594
|
+
server2.registerTool("gog_classroom_coursework_delete", {
|
|
31595
|
+
description: "Delete a coursework item.",
|
|
31596
|
+
annotations: { destructiveHint: true },
|
|
31597
|
+
inputSchema: {
|
|
31598
|
+
courseId: external_exports.string().describe("Course ID"),
|
|
31599
|
+
courseworkId: external_exports.string().describe("Coursework ID"),
|
|
31600
|
+
account: accountParam
|
|
31601
|
+
}
|
|
31602
|
+
}, async ({ courseId, courseworkId, account }) => {
|
|
31603
|
+
return runOrDiagnose(["classroom", "coursework", "delete", courseId, courseworkId], { account });
|
|
31604
|
+
});
|
|
31605
|
+
server2.registerTool("gog_classroom_announcements_update", {
|
|
31606
|
+
description: "Update an existing announcement.",
|
|
31607
|
+
annotations: { destructiveHint: true },
|
|
31608
|
+
inputSchema: {
|
|
31609
|
+
courseId: external_exports.string().describe("Course ID"),
|
|
31610
|
+
announcementId: external_exports.string().describe("Announcement ID"),
|
|
31611
|
+
text: external_exports.string().optional().describe("New text"),
|
|
31612
|
+
state: workState.optional().describe("State"),
|
|
31613
|
+
scheduled: external_exports.string().optional().describe("Scheduled publish time"),
|
|
31614
|
+
account: accountParam
|
|
31615
|
+
}
|
|
31616
|
+
}, async ({ courseId, announcementId, text, state, scheduled, account }) => {
|
|
31617
|
+
const args = ["classroom", "announcements", "update", courseId, announcementId];
|
|
31618
|
+
if (text) args.push(`--text=${text}`);
|
|
31619
|
+
if (state) args.push(`--state=${state}`);
|
|
31620
|
+
if (scheduled) args.push(`--scheduled=${scheduled}`);
|
|
31621
|
+
return runOrDiagnose(args, { account });
|
|
31622
|
+
});
|
|
31623
|
+
server2.registerTool("gog_classroom_announcements_delete", {
|
|
31624
|
+
description: "Delete an announcement.",
|
|
31625
|
+
annotations: { destructiveHint: true },
|
|
31626
|
+
inputSchema: {
|
|
31627
|
+
courseId: external_exports.string().describe("Course ID"),
|
|
31628
|
+
announcementId: external_exports.string().describe("Announcement ID"),
|
|
31629
|
+
account: accountParam
|
|
31630
|
+
}
|
|
31631
|
+
}, async ({ courseId, announcementId, account }) => {
|
|
31632
|
+
return runOrDiagnose(["classroom", "announcements", "delete", courseId, announcementId], { account });
|
|
31633
|
+
});
|
|
31634
|
+
server2.registerTool("gog_classroom_topics_create", {
|
|
31635
|
+
description: "Create a topic in a Google Classroom course.",
|
|
31636
|
+
inputSchema: {
|
|
31637
|
+
courseId: external_exports.string().describe("Course ID"),
|
|
31638
|
+
name: external_exports.string().describe("Topic name"),
|
|
31639
|
+
account: accountParam
|
|
31640
|
+
}
|
|
31641
|
+
}, async ({ courseId, name, account }) => {
|
|
31642
|
+
return runOrDiagnose(["classroom", "topics", "create", courseId, `--name=${name}`], { account });
|
|
31643
|
+
});
|
|
31644
|
+
server2.registerTool("gog_classroom_topics_update", {
|
|
31645
|
+
description: "Rename an existing topic.",
|
|
31646
|
+
annotations: { destructiveHint: true },
|
|
31647
|
+
inputSchema: {
|
|
31648
|
+
courseId: external_exports.string().describe("Course ID"),
|
|
31649
|
+
topicId: external_exports.string().describe("Topic ID"),
|
|
31650
|
+
name: external_exports.string().describe("New topic name"),
|
|
31651
|
+
account: accountParam
|
|
31652
|
+
}
|
|
31653
|
+
}, async ({ courseId, topicId, name, account }) => {
|
|
31654
|
+
return runOrDiagnose(["classroom", "topics", "update", courseId, topicId, `--name=${name}`], { account });
|
|
31655
|
+
});
|
|
31656
|
+
server2.registerTool("gog_classroom_topics_delete", {
|
|
31657
|
+
description: "Delete a topic.",
|
|
31658
|
+
annotations: { destructiveHint: true },
|
|
31659
|
+
inputSchema: {
|
|
31660
|
+
courseId: external_exports.string().describe("Course ID"),
|
|
31661
|
+
topicId: external_exports.string().describe("Topic ID"),
|
|
31662
|
+
account: accountParam
|
|
31663
|
+
}
|
|
31664
|
+
}, async ({ courseId, topicId, account }) => {
|
|
31665
|
+
return runOrDiagnose(["classroom", "topics", "delete", courseId, topicId], { account });
|
|
31666
|
+
});
|
|
31667
|
+
server2.registerTool("gog_classroom_invitations_create", {
|
|
31668
|
+
description: "Create an invitation to a Google Classroom course.",
|
|
31669
|
+
inputSchema: {
|
|
31670
|
+
courseId: external_exports.string().describe("Course ID"),
|
|
31671
|
+
userId: external_exports.string().describe("User ID to invite"),
|
|
31672
|
+
role: external_exports.enum(["STUDENT", "TEACHER", "OWNER"]).describe("Role for the invited user"),
|
|
31673
|
+
account: accountParam
|
|
31674
|
+
}
|
|
31675
|
+
}, async ({ courseId, userId, role, account }) => {
|
|
31676
|
+
return runOrDiagnose(["classroom", "invitations", "create", courseId, userId, `--role=${role}`], { account });
|
|
31677
|
+
});
|
|
31678
|
+
server2.registerTool("gog_classroom_invitations_delete", {
|
|
31679
|
+
description: "Delete (revoke) a Google Classroom invitation.",
|
|
31680
|
+
annotations: { destructiveHint: true },
|
|
31681
|
+
inputSchema: {
|
|
31682
|
+
invitationId: external_exports.string().describe("Invitation ID"),
|
|
31683
|
+
account: accountParam
|
|
31684
|
+
}
|
|
31685
|
+
}, async ({ invitationId, account }) => {
|
|
31686
|
+
return runOrDiagnose(["classroom", "invitations", "delete", invitationId], { account });
|
|
31687
|
+
});
|
|
31692
31688
|
}
|
|
31693
31689
|
|
|
31694
31690
|
// src/index.ts
|
package/manifest.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"manifest_version": "0.3",
|
|
4
4
|
"name": "gogcli-mcp-classroom",
|
|
5
5
|
"display_name": "gogcli (Classroom)",
|
|
6
|
-
"version": "2.0.
|
|
6
|
+
"version": "2.0.6",
|
|
7
7
|
"description": "Extended Google Classroom for Claude via gogcli — auth + full Classroom support (courses, rosters, coursework, submissions, announcements, topics, invitations)",
|
|
8
8
|
"author": {
|
|
9
9
|
"name": "Chris Hall",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gogcli-mcp-classroom",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.6",
|
|
4
4
|
"mcpName": "io.github.chrischall/gogcli-mcp-classroom",
|
|
5
5
|
"description": "Extended Google Classroom MCP server via gogcli — auth + full Classroom support",
|
|
6
6
|
"author": "Claude Code (AI) <https://www.anthropic.com/claude>",
|
package/server.json
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
|
|
3
3
|
"name": "io.github.chrischall/gogcli-mcp-classroom",
|
|
4
|
-
"description": "Google Classroom via gogcli for Claude
|
|
4
|
+
"description": "Google Classroom via gogcli for Claude \u2014 courses, assignments, submissions, grading",
|
|
5
5
|
"repository": {
|
|
6
6
|
"url": "https://github.com/chrischall/gogcli-mcp",
|
|
7
7
|
"source": "github",
|
|
8
8
|
"subfolder": "packages/gogcli-mcp-classroom"
|
|
9
9
|
},
|
|
10
|
-
"version": "2.0.
|
|
10
|
+
"version": "2.0.3",
|
|
11
11
|
"packages": [
|
|
12
12
|
{
|
|
13
13
|
"registryType": "npm",
|
|
14
14
|
"identifier": "gogcli-mcp-classroom",
|
|
15
|
-
"version": "2.0.
|
|
15
|
+
"version": "2.0.3",
|
|
16
16
|
"transport": {
|
|
17
17
|
"type": "stdio"
|
|
18
18
|
},
|
|
@@ -1,5 +1,303 @@
|
|
|
1
1
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { accountParam, runOrDiagnose } from '../../../gogcli-mcp/src/lib.js';
|
|
2
4
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
+
const courseState = z.enum(['ACTIVE', 'ARCHIVED', 'PROVISIONED', 'DECLINED', 'SUSPENDED']);
|
|
6
|
+
const workState = z.enum(['PUBLISHED', 'DRAFT']);
|
|
7
|
+
const workType = z.enum(['ASSIGNMENT', 'SHORT_ANSWER_QUESTION', 'MULTIPLE_CHOICE_QUESTION']);
|
|
8
|
+
|
|
9
|
+
// Fields shared by courses_create and courses_update. `name` is required on
|
|
10
|
+
// create, optional on update — keep it out of this fragment so each tool can
|
|
11
|
+
// declare its own rule.
|
|
12
|
+
const courseSharedFields = {
|
|
13
|
+
owner: z.string().optional().describe('Owner user ID (default "me" on create)'),
|
|
14
|
+
section: z.string().optional().describe('Section'),
|
|
15
|
+
descriptionHeading: z.string().optional().describe('Description heading'),
|
|
16
|
+
description: z.string().optional().describe('Description'),
|
|
17
|
+
room: z.string().optional().describe('Room'),
|
|
18
|
+
state: courseState.optional().describe('Course state'),
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
// Fields shared by coursework_create and coursework_update.
|
|
22
|
+
const courseworkSharedFields = {
|
|
23
|
+
description: z.string().optional().describe('Description'),
|
|
24
|
+
type: workType.optional().describe('Work type (default: ASSIGNMENT)'),
|
|
25
|
+
state: workState.optional().describe('State'),
|
|
26
|
+
maxPoints: z.number().optional().describe('Max points'),
|
|
27
|
+
due: z.string().optional().describe('Due datetime (combined date+time)'),
|
|
28
|
+
dueDate: z.string().optional().describe('Due date (YYYY-MM-DD)'),
|
|
29
|
+
dueTime: z.string().optional().describe('Due time (HH:MM)'),
|
|
30
|
+
scheduled: z.string().optional().describe('Scheduled publish time'),
|
|
31
|
+
topic: z.string().optional().describe('Topic ID'),
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export function registerExtraClassroomTools(server: McpServer): void {
|
|
35
|
+
server.registerTool('gog_classroom_courses_create', {
|
|
36
|
+
description: 'Create a new Google Classroom course.',
|
|
37
|
+
inputSchema: {
|
|
38
|
+
name: z.string().describe('Course name'),
|
|
39
|
+
...courseSharedFields,
|
|
40
|
+
account: accountParam,
|
|
41
|
+
},
|
|
42
|
+
}, async ({ name, owner, section, descriptionHeading, description, room, state, account }) => {
|
|
43
|
+
const args = ['classroom', 'courses', 'create', `--name=${name}`];
|
|
44
|
+
if (owner) args.push(`--owner=${owner}`);
|
|
45
|
+
if (section) args.push(`--section=${section}`);
|
|
46
|
+
if (descriptionHeading) args.push(`--description-heading=${descriptionHeading}`);
|
|
47
|
+
if (description) args.push(`--description=${description}`);
|
|
48
|
+
if (room) args.push(`--room=${room}`);
|
|
49
|
+
if (state) args.push(`--state=${state}`);
|
|
50
|
+
return runOrDiagnose(args, { account });
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
server.registerTool('gog_classroom_courses_update', {
|
|
54
|
+
description: 'Update an existing Google Classroom course.',
|
|
55
|
+
annotations: { destructiveHint: true },
|
|
56
|
+
inputSchema: {
|
|
57
|
+
courseId: z.string().describe('Course ID'),
|
|
58
|
+
name: z.string().optional().describe('Course name'),
|
|
59
|
+
...courseSharedFields,
|
|
60
|
+
account: accountParam,
|
|
61
|
+
},
|
|
62
|
+
}, async ({ courseId, name, owner, section, descriptionHeading, description, room, state, account }) => {
|
|
63
|
+
const args = ['classroom', 'courses', 'update', courseId];
|
|
64
|
+
if (name) args.push(`--name=${name}`);
|
|
65
|
+
if (owner) args.push(`--owner=${owner}`);
|
|
66
|
+
if (section) args.push(`--section=${section}`);
|
|
67
|
+
if (descriptionHeading) args.push(`--description-heading=${descriptionHeading}`);
|
|
68
|
+
if (description) args.push(`--description=${description}`);
|
|
69
|
+
if (room) args.push(`--room=${room}`);
|
|
70
|
+
if (state) args.push(`--state=${state}`);
|
|
71
|
+
return runOrDiagnose(args, { account });
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
server.registerTool('gog_classroom_courses_delete', {
|
|
75
|
+
description: 'Delete a Google Classroom course.',
|
|
76
|
+
annotations: { destructiveHint: true },
|
|
77
|
+
inputSchema: {
|
|
78
|
+
courseId: z.string().describe('Course ID'),
|
|
79
|
+
account: accountParam,
|
|
80
|
+
},
|
|
81
|
+
}, async ({ courseId, account }) => {
|
|
82
|
+
return runOrDiagnose(['classroom', 'courses', 'delete', courseId], { account });
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
server.registerTool('gog_classroom_courses_archive', {
|
|
86
|
+
description: 'Archive a Google Classroom course.',
|
|
87
|
+
annotations: { destructiveHint: true },
|
|
88
|
+
inputSchema: {
|
|
89
|
+
courseId: z.string().describe('Course ID'),
|
|
90
|
+
account: accountParam,
|
|
91
|
+
},
|
|
92
|
+
}, async ({ courseId, account }) => {
|
|
93
|
+
return runOrDiagnose(['classroom', 'courses', 'archive', courseId], { account });
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
server.registerTool('gog_classroom_courses_unarchive', {
|
|
97
|
+
description: 'Unarchive a Google Classroom course (restore to ACTIVE).',
|
|
98
|
+
inputSchema: {
|
|
99
|
+
courseId: z.string().describe('Course ID'),
|
|
100
|
+
account: accountParam,
|
|
101
|
+
},
|
|
102
|
+
}, async ({ courseId, account }) => {
|
|
103
|
+
return runOrDiagnose(['classroom', 'courses', 'unarchive', courseId], { account });
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
server.registerTool('gog_classroom_students_add', {
|
|
107
|
+
description: 'Add a student to a Google Classroom course.',
|
|
108
|
+
inputSchema: {
|
|
109
|
+
courseId: z.string().describe('Course ID'),
|
|
110
|
+
userId: z.string().describe('Student user ID (or "me")'),
|
|
111
|
+
enrollmentCode: z.string().optional().describe('Enrollment code (required if adding self via code)'),
|
|
112
|
+
account: accountParam,
|
|
113
|
+
},
|
|
114
|
+
}, async ({ courseId, userId, enrollmentCode, account }) => {
|
|
115
|
+
const args = ['classroom', 'students', 'add', courseId, userId];
|
|
116
|
+
if (enrollmentCode) args.push(`--enrollment-code=${enrollmentCode}`);
|
|
117
|
+
return runOrDiagnose(args, { account });
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
server.registerTool('gog_classroom_students_remove', {
|
|
121
|
+
description: 'Remove a student from a Google Classroom course.',
|
|
122
|
+
annotations: { destructiveHint: true },
|
|
123
|
+
inputSchema: {
|
|
124
|
+
courseId: z.string().describe('Course ID'),
|
|
125
|
+
userId: z.string().describe('Student user ID'),
|
|
126
|
+
account: accountParam,
|
|
127
|
+
},
|
|
128
|
+
}, async ({ courseId, userId, account }) => {
|
|
129
|
+
return runOrDiagnose(['classroom', 'students', 'remove', courseId, userId], { account });
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
server.registerTool('gog_classroom_teachers_add', {
|
|
133
|
+
description: 'Add a teacher to a Google Classroom course.',
|
|
134
|
+
inputSchema: {
|
|
135
|
+
courseId: z.string().describe('Course ID'),
|
|
136
|
+
userId: z.string().describe('Teacher user ID'),
|
|
137
|
+
account: accountParam,
|
|
138
|
+
},
|
|
139
|
+
}, async ({ courseId, userId, account }) => {
|
|
140
|
+
return runOrDiagnose(['classroom', 'teachers', 'add', courseId, userId], { account });
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
server.registerTool('gog_classroom_teachers_remove', {
|
|
144
|
+
description: 'Remove a teacher from a Google Classroom course.',
|
|
145
|
+
annotations: { destructiveHint: true },
|
|
146
|
+
inputSchema: {
|
|
147
|
+
courseId: z.string().describe('Course ID'),
|
|
148
|
+
userId: z.string().describe('Teacher user ID'),
|
|
149
|
+
account: accountParam,
|
|
150
|
+
},
|
|
151
|
+
}, async ({ courseId, userId, account }) => {
|
|
152
|
+
return runOrDiagnose(['classroom', 'teachers', 'remove', courseId, userId], { account });
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
server.registerTool('gog_classroom_coursework_create', {
|
|
156
|
+
description: 'Create a new coursework item (assignment, question, etc.) in a course.',
|
|
157
|
+
inputSchema: {
|
|
158
|
+
courseId: z.string().describe('Course ID'),
|
|
159
|
+
title: z.string().describe('Coursework title'),
|
|
160
|
+
...courseworkSharedFields,
|
|
161
|
+
account: accountParam,
|
|
162
|
+
},
|
|
163
|
+
}, async ({ courseId, title, description, type, state, maxPoints, due, dueDate, dueTime, scheduled, topic, account }) => {
|
|
164
|
+
const args = ['classroom', 'coursework', 'create', courseId, `--title=${title}`];
|
|
165
|
+
if (description) args.push(`--description=${description}`);
|
|
166
|
+
if (type) args.push(`--type=${type}`);
|
|
167
|
+
if (state) args.push(`--state=${state}`);
|
|
168
|
+
if (maxPoints !== undefined) args.push(`--max-points=${maxPoints}`);
|
|
169
|
+
if (due) args.push(`--due=${due}`);
|
|
170
|
+
if (dueDate) args.push(`--due-date=${dueDate}`);
|
|
171
|
+
if (dueTime) args.push(`--due-time=${dueTime}`);
|
|
172
|
+
if (scheduled) args.push(`--scheduled=${scheduled}`);
|
|
173
|
+
if (topic) args.push(`--topic=${topic}`);
|
|
174
|
+
return runOrDiagnose(args, { account });
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
server.registerTool('gog_classroom_coursework_update', {
|
|
178
|
+
description: 'Update an existing coursework item.',
|
|
179
|
+
annotations: { destructiveHint: true },
|
|
180
|
+
inputSchema: {
|
|
181
|
+
courseId: z.string().describe('Course ID'),
|
|
182
|
+
courseworkId: z.string().describe('Coursework ID'),
|
|
183
|
+
title: z.string().optional().describe('New title'),
|
|
184
|
+
...courseworkSharedFields,
|
|
185
|
+
account: accountParam,
|
|
186
|
+
},
|
|
187
|
+
}, async ({ courseId, courseworkId, title, description, type, state, maxPoints, due, dueDate, dueTime, scheduled, topic, account }) => {
|
|
188
|
+
const args = ['classroom', 'coursework', 'update', courseId, courseworkId];
|
|
189
|
+
if (title) args.push(`--title=${title}`);
|
|
190
|
+
if (description) args.push(`--description=${description}`);
|
|
191
|
+
if (type) args.push(`--type=${type}`);
|
|
192
|
+
if (state) args.push(`--state=${state}`);
|
|
193
|
+
if (maxPoints !== undefined) args.push(`--max-points=${maxPoints}`);
|
|
194
|
+
if (due) args.push(`--due=${due}`);
|
|
195
|
+
if (dueDate) args.push(`--due-date=${dueDate}`);
|
|
196
|
+
if (dueTime) args.push(`--due-time=${dueTime}`);
|
|
197
|
+
if (scheduled) args.push(`--scheduled=${scheduled}`);
|
|
198
|
+
if (topic) args.push(`--topic=${topic}`);
|
|
199
|
+
return runOrDiagnose(args, { account });
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
server.registerTool('gog_classroom_coursework_delete', {
|
|
203
|
+
description: 'Delete a coursework item.',
|
|
204
|
+
annotations: { destructiveHint: true },
|
|
205
|
+
inputSchema: {
|
|
206
|
+
courseId: z.string().describe('Course ID'),
|
|
207
|
+
courseworkId: z.string().describe('Coursework ID'),
|
|
208
|
+
account: accountParam,
|
|
209
|
+
},
|
|
210
|
+
}, async ({ courseId, courseworkId, account }) => {
|
|
211
|
+
return runOrDiagnose(['classroom', 'coursework', 'delete', courseId, courseworkId], { account });
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
server.registerTool('gog_classroom_announcements_update', {
|
|
215
|
+
description: 'Update an existing announcement.',
|
|
216
|
+
annotations: { destructiveHint: true },
|
|
217
|
+
inputSchema: {
|
|
218
|
+
courseId: z.string().describe('Course ID'),
|
|
219
|
+
announcementId: z.string().describe('Announcement ID'),
|
|
220
|
+
text: z.string().optional().describe('New text'),
|
|
221
|
+
state: workState.optional().describe('State'),
|
|
222
|
+
scheduled: z.string().optional().describe('Scheduled publish time'),
|
|
223
|
+
account: accountParam,
|
|
224
|
+
},
|
|
225
|
+
}, async ({ courseId, announcementId, text, state, scheduled, account }) => {
|
|
226
|
+
const args = ['classroom', 'announcements', 'update', courseId, announcementId];
|
|
227
|
+
if (text) args.push(`--text=${text}`);
|
|
228
|
+
if (state) args.push(`--state=${state}`);
|
|
229
|
+
if (scheduled) args.push(`--scheduled=${scheduled}`);
|
|
230
|
+
return runOrDiagnose(args, { account });
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
server.registerTool('gog_classroom_announcements_delete', {
|
|
234
|
+
description: 'Delete an announcement.',
|
|
235
|
+
annotations: { destructiveHint: true },
|
|
236
|
+
inputSchema: {
|
|
237
|
+
courseId: z.string().describe('Course ID'),
|
|
238
|
+
announcementId: z.string().describe('Announcement ID'),
|
|
239
|
+
account: accountParam,
|
|
240
|
+
},
|
|
241
|
+
}, async ({ courseId, announcementId, account }) => {
|
|
242
|
+
return runOrDiagnose(['classroom', 'announcements', 'delete', courseId, announcementId], { account });
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
server.registerTool('gog_classroom_topics_create', {
|
|
246
|
+
description: 'Create a topic in a Google Classroom course.',
|
|
247
|
+
inputSchema: {
|
|
248
|
+
courseId: z.string().describe('Course ID'),
|
|
249
|
+
name: z.string().describe('Topic name'),
|
|
250
|
+
account: accountParam,
|
|
251
|
+
},
|
|
252
|
+
}, async ({ courseId, name, account }) => {
|
|
253
|
+
return runOrDiagnose(['classroom', 'topics', 'create', courseId, `--name=${name}`], { account });
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
server.registerTool('gog_classroom_topics_update', {
|
|
257
|
+
description: 'Rename an existing topic.',
|
|
258
|
+
annotations: { destructiveHint: true },
|
|
259
|
+
inputSchema: {
|
|
260
|
+
courseId: z.string().describe('Course ID'),
|
|
261
|
+
topicId: z.string().describe('Topic ID'),
|
|
262
|
+
name: z.string().describe('New topic name'),
|
|
263
|
+
account: accountParam,
|
|
264
|
+
},
|
|
265
|
+
}, async ({ courseId, topicId, name, account }) => {
|
|
266
|
+
return runOrDiagnose(['classroom', 'topics', 'update', courseId, topicId, `--name=${name}`], { account });
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
server.registerTool('gog_classroom_topics_delete', {
|
|
270
|
+
description: 'Delete a topic.',
|
|
271
|
+
annotations: { destructiveHint: true },
|
|
272
|
+
inputSchema: {
|
|
273
|
+
courseId: z.string().describe('Course ID'),
|
|
274
|
+
topicId: z.string().describe('Topic ID'),
|
|
275
|
+
account: accountParam,
|
|
276
|
+
},
|
|
277
|
+
}, async ({ courseId, topicId, account }) => {
|
|
278
|
+
return runOrDiagnose(['classroom', 'topics', 'delete', courseId, topicId], { account });
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
server.registerTool('gog_classroom_invitations_create', {
|
|
282
|
+
description: 'Create an invitation to a Google Classroom course.',
|
|
283
|
+
inputSchema: {
|
|
284
|
+
courseId: z.string().describe('Course ID'),
|
|
285
|
+
userId: z.string().describe('User ID to invite'),
|
|
286
|
+
role: z.enum(['STUDENT', 'TEACHER', 'OWNER']).describe('Role for the invited user'),
|
|
287
|
+
account: accountParam,
|
|
288
|
+
},
|
|
289
|
+
}, async ({ courseId, userId, role, account }) => {
|
|
290
|
+
return runOrDiagnose(['classroom', 'invitations', 'create', courseId, userId, `--role=${role}`], { account });
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
server.registerTool('gog_classroom_invitations_delete', {
|
|
294
|
+
description: 'Delete (revoke) a Google Classroom invitation.',
|
|
295
|
+
annotations: { destructiveHint: true },
|
|
296
|
+
inputSchema: {
|
|
297
|
+
invitationId: z.string().describe('Invitation ID'),
|
|
298
|
+
account: accountParam,
|
|
299
|
+
},
|
|
300
|
+
}, async ({ invitationId, account }) => {
|
|
301
|
+
return runOrDiagnose(['classroom', 'invitations', 'delete', invitationId], { account });
|
|
302
|
+
});
|
|
5
303
|
}
|
|
@@ -1,12 +1,264 @@
|
|
|
1
|
-
import { describe, it, expect, vi } from 'vitest';
|
|
2
|
-
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
1
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
3
2
|
import { registerExtraClassroomTools } from '../../src/tools/classroom-extra.js';
|
|
3
|
+
import * as lib from '../../../gogcli-mcp/src/lib.js';
|
|
4
|
+
import { setupExtrasHandlers, toText, type ToolHandler } from '../../../gogcli-mcp/tests/helpers/extras-harness.js';
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
vi.mock('../../../gogcli-mcp/src/lib.js', async (importOriginal) => {
|
|
7
|
+
const actual = await importOriginal<typeof lib>();
|
|
8
|
+
return {
|
|
9
|
+
...actual,
|
|
10
|
+
runOrDiagnose: vi.fn(),
|
|
11
|
+
};
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
let handlers: Map<string, ToolHandler>;
|
|
15
|
+
|
|
16
|
+
beforeEach(() => {
|
|
17
|
+
vi.clearAllMocks();
|
|
18
|
+
vi.mocked(lib.runOrDiagnose).mockResolvedValue(toText('{}'));
|
|
19
|
+
handlers = setupExtrasHandlers(registerExtraClassroomTools);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
describe('gog_classroom_courses_create', () => {
|
|
23
|
+
it('calls runOrDiagnose with required name only', async () => {
|
|
24
|
+
await handlers.get('gog_classroom_courses_create')!({ name: 'Math 101' });
|
|
25
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
26
|
+
['classroom', 'courses', 'create', '--name=Math 101'],
|
|
27
|
+
{ account: undefined },
|
|
28
|
+
);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('passes all optional flags', async () => {
|
|
32
|
+
await handlers.get('gog_classroom_courses_create')!({
|
|
33
|
+
name: 'Math 101',
|
|
34
|
+
owner: 'me',
|
|
35
|
+
section: 'Section A',
|
|
36
|
+
descriptionHeading: 'Welcome',
|
|
37
|
+
description: 'Algebra',
|
|
38
|
+
room: 'R101',
|
|
39
|
+
state: 'ACTIVE',
|
|
40
|
+
});
|
|
41
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
42
|
+
['classroom', 'courses', 'create', '--name=Math 101', '--owner=me', '--section=Section A', '--description-heading=Welcome', '--description=Algebra', '--room=R101', '--state=ACTIVE'],
|
|
43
|
+
{ account: undefined },
|
|
44
|
+
);
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
describe('gog_classroom_courses_update', () => {
|
|
49
|
+
it('calls runOrDiagnose with courseId only', async () => {
|
|
50
|
+
await handlers.get('gog_classroom_courses_update')!({ courseId: 'c1' });
|
|
51
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['classroom', 'courses', 'update', 'c1'], { account: undefined });
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('passes all optional flags', async () => {
|
|
55
|
+
await handlers.get('gog_classroom_courses_update')!({
|
|
56
|
+
courseId: 'c1',
|
|
57
|
+
name: 'New Name',
|
|
58
|
+
owner: 'me',
|
|
59
|
+
section: 'B',
|
|
60
|
+
descriptionHeading: 'Heading',
|
|
61
|
+
description: 'Desc',
|
|
62
|
+
room: 'R2',
|
|
63
|
+
state: 'ARCHIVED',
|
|
64
|
+
});
|
|
65
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
66
|
+
['classroom', 'courses', 'update', 'c1', '--name=New Name', '--owner=me', '--section=B', '--description-heading=Heading', '--description=Desc', '--room=R2', '--state=ARCHIVED'],
|
|
67
|
+
{ account: undefined },
|
|
68
|
+
);
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
describe('gog_classroom_courses_delete', () => {
|
|
73
|
+
it('calls runOrDiagnose with courseId', async () => {
|
|
74
|
+
await handlers.get('gog_classroom_courses_delete')!({ courseId: 'c1' });
|
|
75
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['classroom', 'courses', 'delete', 'c1'], { account: undefined });
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
describe('gog_classroom_courses_archive', () => {
|
|
80
|
+
it('calls runOrDiagnose with courseId', async () => {
|
|
81
|
+
await handlers.get('gog_classroom_courses_archive')!({ courseId: 'c1' });
|
|
82
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['classroom', 'courses', 'archive', 'c1'], { account: undefined });
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
describe('gog_classroom_courses_unarchive', () => {
|
|
87
|
+
it('calls runOrDiagnose with courseId', async () => {
|
|
88
|
+
await handlers.get('gog_classroom_courses_unarchive')!({ courseId: 'c1' });
|
|
89
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['classroom', 'courses', 'unarchive', 'c1'], { account: undefined });
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
describe('gog_classroom_students_add', () => {
|
|
94
|
+
it('calls runOrDiagnose with courseId and userId', async () => {
|
|
95
|
+
await handlers.get('gog_classroom_students_add')!({ courseId: 'c1', userId: 'u1' });
|
|
96
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['classroom', 'students', 'add', 'c1', 'u1'], { account: undefined });
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('passes --enrollment-code when provided', async () => {
|
|
100
|
+
await handlers.get('gog_classroom_students_add')!({ courseId: 'c1', userId: 'u1', enrollmentCode: 'abc123' });
|
|
101
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
102
|
+
['classroom', 'students', 'add', 'c1', 'u1', '--enrollment-code=abc123'],
|
|
103
|
+
{ account: undefined },
|
|
104
|
+
);
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
describe('gog_classroom_students_remove', () => {
|
|
109
|
+
it('calls runOrDiagnose with courseId and userId', async () => {
|
|
110
|
+
await handlers.get('gog_classroom_students_remove')!({ courseId: 'c1', userId: 'u1' });
|
|
111
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['classroom', 'students', 'remove', 'c1', 'u1'], { account: undefined });
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
describe('gog_classroom_teachers_add', () => {
|
|
116
|
+
it('calls runOrDiagnose with courseId and userId', async () => {
|
|
117
|
+
await handlers.get('gog_classroom_teachers_add')!({ courseId: 'c1', userId: 'u1' });
|
|
118
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['classroom', 'teachers', 'add', 'c1', 'u1'], { account: undefined });
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
describe('gog_classroom_teachers_remove', () => {
|
|
123
|
+
it('calls runOrDiagnose with courseId and userId', async () => {
|
|
124
|
+
await handlers.get('gog_classroom_teachers_remove')!({ courseId: 'c1', userId: 'u1' });
|
|
125
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['classroom', 'teachers', 'remove', 'c1', 'u1'], { account: undefined });
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
describe('gog_classroom_coursework_create', () => {
|
|
130
|
+
it('calls runOrDiagnose with required title only', async () => {
|
|
131
|
+
await handlers.get('gog_classroom_coursework_create')!({ courseId: 'c1', title: 'HW1' });
|
|
132
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
133
|
+
['classroom', 'coursework', 'create', 'c1', '--title=HW1'],
|
|
134
|
+
{ account: undefined },
|
|
135
|
+
);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it('passes all optional flags', async () => {
|
|
139
|
+
await handlers.get('gog_classroom_coursework_create')!({
|
|
140
|
+
courseId: 'c1',
|
|
141
|
+
title: 'HW1',
|
|
142
|
+
description: 'Chapter 1',
|
|
143
|
+
type: 'ASSIGNMENT',
|
|
144
|
+
state: 'PUBLISHED',
|
|
145
|
+
maxPoints: 100,
|
|
146
|
+
due: '2026-05-01T23:59',
|
|
147
|
+
dueDate: '2026-05-01',
|
|
148
|
+
dueTime: '23:59',
|
|
149
|
+
scheduled: '2026-04-30T12:00',
|
|
150
|
+
topic: 't1',
|
|
151
|
+
});
|
|
152
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
153
|
+
['classroom', 'coursework', 'create', 'c1', '--title=HW1', '--description=Chapter 1', '--type=ASSIGNMENT', '--state=PUBLISHED', '--max-points=100', '--due=2026-05-01T23:59', '--due-date=2026-05-01', '--due-time=23:59', '--scheduled=2026-04-30T12:00', '--topic=t1'],
|
|
154
|
+
{ account: undefined },
|
|
155
|
+
);
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
describe('gog_classroom_coursework_update', () => {
|
|
160
|
+
it('calls runOrDiagnose with ids only', async () => {
|
|
161
|
+
await handlers.get('gog_classroom_coursework_update')!({ courseId: 'c1', courseworkId: 'w1' });
|
|
162
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['classroom', 'coursework', 'update', 'c1', 'w1'], { account: undefined });
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it('passes all optional flags', async () => {
|
|
166
|
+
await handlers.get('gog_classroom_coursework_update')!({
|
|
167
|
+
courseId: 'c1',
|
|
168
|
+
courseworkId: 'w1',
|
|
169
|
+
title: 'New Title',
|
|
170
|
+
description: 'Desc',
|
|
171
|
+
type: 'SHORT_ANSWER_QUESTION',
|
|
172
|
+
state: 'DRAFT',
|
|
173
|
+
maxPoints: 50,
|
|
174
|
+
due: '2026-05-01T23:59',
|
|
175
|
+
dueDate: '2026-05-01',
|
|
176
|
+
dueTime: '23:59',
|
|
177
|
+
scheduled: '2026-04-30T12:00',
|
|
178
|
+
topic: 't1',
|
|
179
|
+
});
|
|
180
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
181
|
+
['classroom', 'coursework', 'update', 'c1', 'w1', '--title=New Title', '--description=Desc', '--type=SHORT_ANSWER_QUESTION', '--state=DRAFT', '--max-points=50', '--due=2026-05-01T23:59', '--due-date=2026-05-01', '--due-time=23:59', '--scheduled=2026-04-30T12:00', '--topic=t1'],
|
|
182
|
+
{ account: undefined },
|
|
183
|
+
);
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
describe('gog_classroom_coursework_delete', () => {
|
|
188
|
+
it('calls runOrDiagnose with ids', async () => {
|
|
189
|
+
await handlers.get('gog_classroom_coursework_delete')!({ courseId: 'c1', courseworkId: 'w1' });
|
|
190
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['classroom', 'coursework', 'delete', 'c1', 'w1'], { account: undefined });
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
describe('gog_classroom_announcements_update', () => {
|
|
195
|
+
it('calls runOrDiagnose with ids only', async () => {
|
|
196
|
+
await handlers.get('gog_classroom_announcements_update')!({ courseId: 'c1', announcementId: 'a1' });
|
|
197
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['classroom', 'announcements', 'update', 'c1', 'a1'], { account: undefined });
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
it('passes all optional flags', async () => {
|
|
201
|
+
await handlers.get('gog_classroom_announcements_update')!({
|
|
202
|
+
courseId: 'c1',
|
|
203
|
+
announcementId: 'a1',
|
|
204
|
+
text: 'edited',
|
|
205
|
+
state: 'PUBLISHED',
|
|
206
|
+
scheduled: '2026-05-01T12:00',
|
|
207
|
+
});
|
|
208
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
209
|
+
['classroom', 'announcements', 'update', 'c1', 'a1', '--text=edited', '--state=PUBLISHED', '--scheduled=2026-05-01T12:00'],
|
|
210
|
+
{ account: undefined },
|
|
211
|
+
);
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
describe('gog_classroom_announcements_delete', () => {
|
|
216
|
+
it('calls runOrDiagnose with ids', async () => {
|
|
217
|
+
await handlers.get('gog_classroom_announcements_delete')!({ courseId: 'c1', announcementId: 'a1' });
|
|
218
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['classroom', 'announcements', 'delete', 'c1', 'a1'], { account: undefined });
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
describe('gog_classroom_topics_create', () => {
|
|
223
|
+
it('calls runOrDiagnose with courseId and name', async () => {
|
|
224
|
+
await handlers.get('gog_classroom_topics_create')!({ courseId: 'c1', name: 'Week 1' });
|
|
225
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
226
|
+
['classroom', 'topics', 'create', 'c1', '--name=Week 1'],
|
|
227
|
+
{ account: undefined },
|
|
228
|
+
);
|
|
229
|
+
});
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
describe('gog_classroom_topics_update', () => {
|
|
233
|
+
it('calls runOrDiagnose with ids and name', async () => {
|
|
234
|
+
await handlers.get('gog_classroom_topics_update')!({ courseId: 'c1', topicId: 't1', name: 'Week 2' });
|
|
235
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
236
|
+
['classroom', 'topics', 'update', 'c1', 't1', '--name=Week 2'],
|
|
237
|
+
{ account: undefined },
|
|
238
|
+
);
|
|
239
|
+
});
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
describe('gog_classroom_topics_delete', () => {
|
|
243
|
+
it('calls runOrDiagnose with ids', async () => {
|
|
244
|
+
await handlers.get('gog_classroom_topics_delete')!({ courseId: 'c1', topicId: 't1' });
|
|
245
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['classroom', 'topics', 'delete', 'c1', 't1'], { account: undefined });
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
describe('gog_classroom_invitations_create', () => {
|
|
250
|
+
it('calls runOrDiagnose with courseId, userId, role', async () => {
|
|
251
|
+
await handlers.get('gog_classroom_invitations_create')!({ courseId: 'c1', userId: 'u1', role: 'STUDENT' });
|
|
252
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
253
|
+
['classroom', 'invitations', 'create', 'c1', 'u1', '--role=STUDENT'],
|
|
254
|
+
{ account: undefined },
|
|
255
|
+
);
|
|
256
|
+
});
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
describe('gog_classroom_invitations_delete', () => {
|
|
260
|
+
it('calls runOrDiagnose with invitationId', async () => {
|
|
261
|
+
await handlers.get('gog_classroom_invitations_delete')!({ invitationId: 'i1' });
|
|
262
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['classroom', 'invitations', 'delete', 'i1'], { account: undefined });
|
|
11
263
|
});
|
|
12
264
|
});
|