gogcli-mcp-classroom 2.0.4 → 2.0.7
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 +283 -282
- package/manifest.json +1 -1
- package/package.json +1 -1
- package/server.json +2 -2
- package/src/tools/classroom-extra.ts +300 -2
- package/tests/tools/classroom-extra.test.ts +260 -8
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
},
|
|
8
8
|
"metadata": {
|
|
9
9
|
"description": "Extended Google Classroom for Claude via gogcli — auth + full Classroom support (courses, rosters, coursework, submissions, announcements, topics, invitations)",
|
|
10
|
-
"version": "2.0.
|
|
10
|
+
"version": "2.0.7"
|
|
11
11
|
},
|
|
12
12
|
"plugins": [
|
|
13
13
|
{
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"displayName": "gogcli (Classroom)",
|
|
16
16
|
"source": "./",
|
|
17
17
|
"description": "Extended Google Classroom for Claude via gogcli — auth + full Classroom support (courses, rosters, coursework, submissions, announcements, topics, invitations)",
|
|
18
|
-
"version": "2.0.
|
|
18
|
+
"version": "2.0.7",
|
|
19
19
|
"author": {
|
|
20
20
|
"name": "Chris Hall"
|
|
21
21
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gogcli-mcp-classroom",
|
|
3
3
|
"displayName": "gogcli (Classroom)",
|
|
4
|
-
"version": "2.0.
|
|
4
|
+
"version": "2.0.7",
|
|
5
5
|
"description": "Extended Google Classroom for Claude via gogcli — auth + full Classroom support (courses, rosters, coursework, submissions, announcements, topics, invitations)",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Chris Hall",
|
package/dist/index.js
CHANGED
|
@@ -30864,6 +30864,11 @@ var EMPTY_COMPLETION_RESULT = {
|
|
|
30864
30864
|
// ../gogcli-mcp/src/runner.ts
|
|
30865
30865
|
import { spawn } from "node:child_process";
|
|
30866
30866
|
var TIMEOUT_MS = 3e4;
|
|
30867
|
+
function envOrUndefined(key) {
|
|
30868
|
+
const value = process.env[key];
|
|
30869
|
+
if (!value || value.startsWith("${")) return void 0;
|
|
30870
|
+
return value;
|
|
30871
|
+
}
|
|
30867
30872
|
function formatTimeout(ms) {
|
|
30868
30873
|
const seconds = Math.round(ms / 1e3);
|
|
30869
30874
|
if (seconds >= 60) {
|
|
@@ -30874,7 +30879,7 @@ function formatTimeout(ms) {
|
|
|
30874
30879
|
}
|
|
30875
30880
|
async function run(args, options = {}) {
|
|
30876
30881
|
const { account, spawner = spawn, interactive = false, timeout } = options;
|
|
30877
|
-
const effectiveAccount = account ??
|
|
30882
|
+
const effectiveAccount = account ?? envOrUndefined("GOG_ACCOUNT");
|
|
30878
30883
|
const fullArgs = ["--json", "--color=never"];
|
|
30879
30884
|
if (!interactive) {
|
|
30880
30885
|
fullArgs.push("--no-input");
|
|
@@ -30886,7 +30891,7 @@ async function run(args, options = {}) {
|
|
|
30886
30891
|
const effectiveTimeout = timeout ?? TIMEOUT_MS;
|
|
30887
30892
|
return new Promise((resolve, reject) => {
|
|
30888
30893
|
const { GOG_ACCESS_TOKEN: _, ...cleanEnv } = process.env;
|
|
30889
|
-
const child = spawner(
|
|
30894
|
+
const child = spawner(envOrUndefined("GOG_PATH") ?? "gog", fullArgs, { env: cleanEnv });
|
|
30890
30895
|
const stdoutChunks = [];
|
|
30891
30896
|
const stderrChunks = [];
|
|
30892
30897
|
let settled = false;
|
|
@@ -31061,83 +31066,6 @@ function registerClassroomTools(server2) {
|
|
|
31061
31066
|
}, async ({ courseId, account }) => {
|
|
31062
31067
|
return runOrDiagnose(["classroom", "courses", "get", courseId], { account });
|
|
31063
31068
|
});
|
|
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
31069
|
server2.registerTool("gog_classroom_students_list", {
|
|
31142
31070
|
description: "List students enrolled in a Google Classroom course.",
|
|
31143
31071
|
annotations: { readOnlyHint: true },
|
|
@@ -31166,30 +31094,6 @@ function registerClassroomTools(server2) {
|
|
|
31166
31094
|
}, async ({ courseId, userId, account }) => {
|
|
31167
31095
|
return runOrDiagnose(["classroom", "students", "get", courseId, userId], { account });
|
|
31168
31096
|
});
|
|
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
31097
|
server2.registerTool("gog_classroom_teachers_list", {
|
|
31194
31098
|
description: "List teachers in a Google Classroom course.",
|
|
31195
31099
|
annotations: { readOnlyHint: true },
|
|
@@ -31218,27 +31122,6 @@ function registerClassroomTools(server2) {
|
|
|
31218
31122
|
}, async ({ courseId, userId, account }) => {
|
|
31219
31123
|
return runOrDiagnose(["classroom", "teachers", "get", courseId, userId], { account });
|
|
31220
31124
|
});
|
|
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
31125
|
server2.registerTool("gog_classroom_roster", {
|
|
31243
31126
|
description: "List the full roster (students and/or teachers) of a Google Classroom course. Omit both flags to return both groups.",
|
|
31244
31127
|
annotations: { readOnlyHint: true },
|
|
@@ -31296,78 +31179,6 @@ function registerClassroomTools(server2) {
|
|
|
31296
31179
|
}, async ({ courseId, courseworkId, account }) => {
|
|
31297
31180
|
return runOrDiagnose(["classroom", "coursework", "get", courseId, courseworkId], { account });
|
|
31298
31181
|
});
|
|
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
31182
|
server2.registerTool("gog_classroom_submissions_list", {
|
|
31372
31183
|
description: "List student submissions for a coursework item.",
|
|
31373
31184
|
annotations: { readOnlyHint: true },
|
|
@@ -31494,7 +31305,7 @@ function registerClassroomTools(server2) {
|
|
|
31494
31305
|
inputSchema: {
|
|
31495
31306
|
courseId: external_exports.string().describe("Course ID"),
|
|
31496
31307
|
text: external_exports.string().describe("Announcement text"),
|
|
31497
|
-
state: external_exports.
|
|
31308
|
+
state: external_exports.enum(["PUBLISHED", "DRAFT"]).optional().describe("State"),
|
|
31498
31309
|
scheduled: external_exports.string().optional().describe("Scheduled publish time"),
|
|
31499
31310
|
account: accountParam
|
|
31500
31311
|
}
|
|
@@ -31504,35 +31315,6 @@ function registerClassroomTools(server2) {
|
|
|
31504
31315
|
if (scheduled) args.push(`--scheduled=${scheduled}`);
|
|
31505
31316
|
return runOrDiagnose(args, { account });
|
|
31506
31317
|
});
|
|
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
31318
|
server2.registerTool("gog_classroom_topics_list", {
|
|
31537
31319
|
description: "List topics in a Google Classroom course.",
|
|
31538
31320
|
annotations: { readOnlyHint: true },
|
|
@@ -31561,39 +31343,6 @@ function registerClassroomTools(server2) {
|
|
|
31561
31343
|
}, async ({ courseId, topicId, account }) => {
|
|
31562
31344
|
return runOrDiagnose(["classroom", "topics", "get", courseId, topicId], { account });
|
|
31563
31345
|
});
|
|
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
31346
|
server2.registerTool("gog_classroom_invitations_list", {
|
|
31598
31347
|
description: "List Google Classroom invitations.",
|
|
31599
31348
|
annotations: { readOnlyHint: true },
|
|
@@ -31624,17 +31373,6 @@ function registerClassroomTools(server2) {
|
|
|
31624
31373
|
}, async ({ invitationId, account }) => {
|
|
31625
31374
|
return runOrDiagnose(["classroom", "invitations", "get", invitationId], { account });
|
|
31626
31375
|
});
|
|
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
31376
|
server2.registerTool("gog_classroom_invitations_accept", {
|
|
31639
31377
|
description: "Accept a Google Classroom invitation.",
|
|
31640
31378
|
inputSchema: {
|
|
@@ -31644,16 +31382,6 @@ function registerClassroomTools(server2) {
|
|
|
31644
31382
|
}, async ({ invitationId, account }) => {
|
|
31645
31383
|
return runOrDiagnose(["classroom", "invitations", "accept", invitationId], { account });
|
|
31646
31384
|
});
|
|
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
31385
|
server2.registerTool("gog_classroom_profile_get", {
|
|
31658
31386
|
description: "Get a Google Classroom user profile. Omit userId to fetch the authenticated user.",
|
|
31659
31387
|
annotations: { readOnlyHint: true },
|
|
@@ -31668,6 +31396,7 @@ function registerClassroomTools(server2) {
|
|
|
31668
31396
|
});
|
|
31669
31397
|
server2.registerTool("gog_classroom_run", {
|
|
31670
31398
|
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.",
|
|
31399
|
+
annotations: { destructiveHint: true },
|
|
31671
31400
|
inputSchema: {
|
|
31672
31401
|
subcommand: external_exports.string().describe('The gog classroom subcommand to run, e.g. "guardians", "materials", "guardian-invitations"'),
|
|
31673
31402
|
args: external_exports.array(external_exports.string()).describe("Additional positional args and flags"),
|
|
@@ -31679,7 +31408,7 @@ function registerClassroomTools(server2) {
|
|
|
31679
31408
|
}
|
|
31680
31409
|
|
|
31681
31410
|
// ../gogcli-mcp/src/server.ts
|
|
31682
|
-
var VERSION = true ? "2.0.
|
|
31411
|
+
var VERSION = true ? "2.0.7" : "0.0.0";
|
|
31683
31412
|
function createServer(options) {
|
|
31684
31413
|
return new McpServer({
|
|
31685
31414
|
name: options?.name ?? "gogcli",
|
|
@@ -31688,7 +31417,279 @@ function createServer(options) {
|
|
|
31688
31417
|
}
|
|
31689
31418
|
|
|
31690
31419
|
// src/tools/classroom-extra.ts
|
|
31691
|
-
|
|
31420
|
+
var courseState = external_exports.enum(["ACTIVE", "ARCHIVED", "PROVISIONED", "DECLINED", "SUSPENDED"]);
|
|
31421
|
+
var workState = external_exports.enum(["PUBLISHED", "DRAFT"]);
|
|
31422
|
+
var workType = external_exports.enum(["ASSIGNMENT", "SHORT_ANSWER_QUESTION", "MULTIPLE_CHOICE_QUESTION"]);
|
|
31423
|
+
var courseSharedFields = {
|
|
31424
|
+
owner: external_exports.string().optional().describe('Owner user ID (default "me" on create)'),
|
|
31425
|
+
section: external_exports.string().optional().describe("Section"),
|
|
31426
|
+
descriptionHeading: external_exports.string().optional().describe("Description heading"),
|
|
31427
|
+
description: external_exports.string().optional().describe("Description"),
|
|
31428
|
+
room: external_exports.string().optional().describe("Room"),
|
|
31429
|
+
state: courseState.optional().describe("Course state")
|
|
31430
|
+
};
|
|
31431
|
+
var courseworkSharedFields = {
|
|
31432
|
+
description: external_exports.string().optional().describe("Description"),
|
|
31433
|
+
type: workType.optional().describe("Work type (default: ASSIGNMENT)"),
|
|
31434
|
+
state: workState.optional().describe("State"),
|
|
31435
|
+
maxPoints: external_exports.number().optional().describe("Max points"),
|
|
31436
|
+
due: external_exports.string().optional().describe("Due datetime (combined date+time)"),
|
|
31437
|
+
dueDate: external_exports.string().optional().describe("Due date (YYYY-MM-DD)"),
|
|
31438
|
+
dueTime: external_exports.string().optional().describe("Due time (HH:MM)"),
|
|
31439
|
+
scheduled: external_exports.string().optional().describe("Scheduled publish time"),
|
|
31440
|
+
topic: external_exports.string().optional().describe("Topic ID")
|
|
31441
|
+
};
|
|
31442
|
+
function registerExtraClassroomTools(server2) {
|
|
31443
|
+
server2.registerTool("gog_classroom_courses_create", {
|
|
31444
|
+
description: "Create a new Google Classroom course.",
|
|
31445
|
+
inputSchema: {
|
|
31446
|
+
name: external_exports.string().describe("Course name"),
|
|
31447
|
+
...courseSharedFields,
|
|
31448
|
+
account: accountParam
|
|
31449
|
+
}
|
|
31450
|
+
}, async ({ name, owner, section, descriptionHeading, description, room, state, account }) => {
|
|
31451
|
+
const args = ["classroom", "courses", "create", `--name=${name}`];
|
|
31452
|
+
if (owner) args.push(`--owner=${owner}`);
|
|
31453
|
+
if (section) args.push(`--section=${section}`);
|
|
31454
|
+
if (descriptionHeading) args.push(`--description-heading=${descriptionHeading}`);
|
|
31455
|
+
if (description) args.push(`--description=${description}`);
|
|
31456
|
+
if (room) args.push(`--room=${room}`);
|
|
31457
|
+
if (state) args.push(`--state=${state}`);
|
|
31458
|
+
return runOrDiagnose(args, { account });
|
|
31459
|
+
});
|
|
31460
|
+
server2.registerTool("gog_classroom_courses_update", {
|
|
31461
|
+
description: "Update an existing Google Classroom course.",
|
|
31462
|
+
annotations: { destructiveHint: true },
|
|
31463
|
+
inputSchema: {
|
|
31464
|
+
courseId: external_exports.string().describe("Course ID"),
|
|
31465
|
+
name: external_exports.string().optional().describe("Course name"),
|
|
31466
|
+
...courseSharedFields,
|
|
31467
|
+
account: accountParam
|
|
31468
|
+
}
|
|
31469
|
+
}, async ({ courseId, name, owner, section, descriptionHeading, description, room, state, account }) => {
|
|
31470
|
+
const args = ["classroom", "courses", "update", courseId];
|
|
31471
|
+
if (name) args.push(`--name=${name}`);
|
|
31472
|
+
if (owner) args.push(`--owner=${owner}`);
|
|
31473
|
+
if (section) args.push(`--section=${section}`);
|
|
31474
|
+
if (descriptionHeading) args.push(`--description-heading=${descriptionHeading}`);
|
|
31475
|
+
if (description) args.push(`--description=${description}`);
|
|
31476
|
+
if (room) args.push(`--room=${room}`);
|
|
31477
|
+
if (state) args.push(`--state=${state}`);
|
|
31478
|
+
return runOrDiagnose(args, { account });
|
|
31479
|
+
});
|
|
31480
|
+
server2.registerTool("gog_classroom_courses_delete", {
|
|
31481
|
+
description: "Delete a Google Classroom course.",
|
|
31482
|
+
annotations: { destructiveHint: true },
|
|
31483
|
+
inputSchema: {
|
|
31484
|
+
courseId: external_exports.string().describe("Course ID"),
|
|
31485
|
+
account: accountParam
|
|
31486
|
+
}
|
|
31487
|
+
}, async ({ courseId, account }) => {
|
|
31488
|
+
return runOrDiagnose(["classroom", "courses", "delete", courseId], { account });
|
|
31489
|
+
});
|
|
31490
|
+
server2.registerTool("gog_classroom_courses_archive", {
|
|
31491
|
+
description: "Archive a Google Classroom course.",
|
|
31492
|
+
annotations: { destructiveHint: true },
|
|
31493
|
+
inputSchema: {
|
|
31494
|
+
courseId: external_exports.string().describe("Course ID"),
|
|
31495
|
+
account: accountParam
|
|
31496
|
+
}
|
|
31497
|
+
}, async ({ courseId, account }) => {
|
|
31498
|
+
return runOrDiagnose(["classroom", "courses", "archive", courseId], { account });
|
|
31499
|
+
});
|
|
31500
|
+
server2.registerTool("gog_classroom_courses_unarchive", {
|
|
31501
|
+
description: "Unarchive a Google Classroom course (restore to ACTIVE).",
|
|
31502
|
+
inputSchema: {
|
|
31503
|
+
courseId: external_exports.string().describe("Course ID"),
|
|
31504
|
+
account: accountParam
|
|
31505
|
+
}
|
|
31506
|
+
}, async ({ courseId, account }) => {
|
|
31507
|
+
return runOrDiagnose(["classroom", "courses", "unarchive", courseId], { account });
|
|
31508
|
+
});
|
|
31509
|
+
server2.registerTool("gog_classroom_students_add", {
|
|
31510
|
+
description: "Add a student to a Google Classroom course.",
|
|
31511
|
+
inputSchema: {
|
|
31512
|
+
courseId: external_exports.string().describe("Course ID"),
|
|
31513
|
+
userId: external_exports.string().describe('Student user ID (or "me")'),
|
|
31514
|
+
enrollmentCode: external_exports.string().optional().describe("Enrollment code (required if adding self via code)"),
|
|
31515
|
+
account: accountParam
|
|
31516
|
+
}
|
|
31517
|
+
}, async ({ courseId, userId, enrollmentCode, account }) => {
|
|
31518
|
+
const args = ["classroom", "students", "add", courseId, userId];
|
|
31519
|
+
if (enrollmentCode) args.push(`--enrollment-code=${enrollmentCode}`);
|
|
31520
|
+
return runOrDiagnose(args, { account });
|
|
31521
|
+
});
|
|
31522
|
+
server2.registerTool("gog_classroom_students_remove", {
|
|
31523
|
+
description: "Remove a student from a Google Classroom course.",
|
|
31524
|
+
annotations: { destructiveHint: true },
|
|
31525
|
+
inputSchema: {
|
|
31526
|
+
courseId: external_exports.string().describe("Course ID"),
|
|
31527
|
+
userId: external_exports.string().describe("Student user ID"),
|
|
31528
|
+
account: accountParam
|
|
31529
|
+
}
|
|
31530
|
+
}, async ({ courseId, userId, account }) => {
|
|
31531
|
+
return runOrDiagnose(["classroom", "students", "remove", courseId, userId], { account });
|
|
31532
|
+
});
|
|
31533
|
+
server2.registerTool("gog_classroom_teachers_add", {
|
|
31534
|
+
description: "Add a teacher to a Google Classroom course.",
|
|
31535
|
+
inputSchema: {
|
|
31536
|
+
courseId: external_exports.string().describe("Course ID"),
|
|
31537
|
+
userId: external_exports.string().describe("Teacher user ID"),
|
|
31538
|
+
account: accountParam
|
|
31539
|
+
}
|
|
31540
|
+
}, async ({ courseId, userId, account }) => {
|
|
31541
|
+
return runOrDiagnose(["classroom", "teachers", "add", courseId, userId], { account });
|
|
31542
|
+
});
|
|
31543
|
+
server2.registerTool("gog_classroom_teachers_remove", {
|
|
31544
|
+
description: "Remove a teacher from a Google Classroom course.",
|
|
31545
|
+
annotations: { destructiveHint: true },
|
|
31546
|
+
inputSchema: {
|
|
31547
|
+
courseId: external_exports.string().describe("Course ID"),
|
|
31548
|
+
userId: external_exports.string().describe("Teacher user ID"),
|
|
31549
|
+
account: accountParam
|
|
31550
|
+
}
|
|
31551
|
+
}, async ({ courseId, userId, account }) => {
|
|
31552
|
+
return runOrDiagnose(["classroom", "teachers", "remove", courseId, userId], { account });
|
|
31553
|
+
});
|
|
31554
|
+
server2.registerTool("gog_classroom_coursework_create", {
|
|
31555
|
+
description: "Create a new coursework item (assignment, question, etc.) in a course.",
|
|
31556
|
+
inputSchema: {
|
|
31557
|
+
courseId: external_exports.string().describe("Course ID"),
|
|
31558
|
+
title: external_exports.string().describe("Coursework title"),
|
|
31559
|
+
...courseworkSharedFields,
|
|
31560
|
+
account: accountParam
|
|
31561
|
+
}
|
|
31562
|
+
}, async ({ courseId, title, description, type, state, maxPoints, due, dueDate, dueTime, scheduled, topic, account }) => {
|
|
31563
|
+
const args = ["classroom", "coursework", "create", courseId, `--title=${title}`];
|
|
31564
|
+
if (description) args.push(`--description=${description}`);
|
|
31565
|
+
if (type) args.push(`--type=${type}`);
|
|
31566
|
+
if (state) args.push(`--state=${state}`);
|
|
31567
|
+
if (maxPoints !== void 0) args.push(`--max-points=${maxPoints}`);
|
|
31568
|
+
if (due) args.push(`--due=${due}`);
|
|
31569
|
+
if (dueDate) args.push(`--due-date=${dueDate}`);
|
|
31570
|
+
if (dueTime) args.push(`--due-time=${dueTime}`);
|
|
31571
|
+
if (scheduled) args.push(`--scheduled=${scheduled}`);
|
|
31572
|
+
if (topic) args.push(`--topic=${topic}`);
|
|
31573
|
+
return runOrDiagnose(args, { account });
|
|
31574
|
+
});
|
|
31575
|
+
server2.registerTool("gog_classroom_coursework_update", {
|
|
31576
|
+
description: "Update an existing coursework item.",
|
|
31577
|
+
annotations: { destructiveHint: true },
|
|
31578
|
+
inputSchema: {
|
|
31579
|
+
courseId: external_exports.string().describe("Course ID"),
|
|
31580
|
+
courseworkId: external_exports.string().describe("Coursework ID"),
|
|
31581
|
+
title: external_exports.string().optional().describe("New title"),
|
|
31582
|
+
...courseworkSharedFields,
|
|
31583
|
+
account: accountParam
|
|
31584
|
+
}
|
|
31585
|
+
}, async ({ courseId, courseworkId, title, description, type, state, maxPoints, due, dueDate, dueTime, scheduled, topic, account }) => {
|
|
31586
|
+
const args = ["classroom", "coursework", "update", courseId, courseworkId];
|
|
31587
|
+
if (title) args.push(`--title=${title}`);
|
|
31588
|
+
if (description) args.push(`--description=${description}`);
|
|
31589
|
+
if (type) args.push(`--type=${type}`);
|
|
31590
|
+
if (state) args.push(`--state=${state}`);
|
|
31591
|
+
if (maxPoints !== void 0) args.push(`--max-points=${maxPoints}`);
|
|
31592
|
+
if (due) args.push(`--due=${due}`);
|
|
31593
|
+
if (dueDate) args.push(`--due-date=${dueDate}`);
|
|
31594
|
+
if (dueTime) args.push(`--due-time=${dueTime}`);
|
|
31595
|
+
if (scheduled) args.push(`--scheduled=${scheduled}`);
|
|
31596
|
+
if (topic) args.push(`--topic=${topic}`);
|
|
31597
|
+
return runOrDiagnose(args, { account });
|
|
31598
|
+
});
|
|
31599
|
+
server2.registerTool("gog_classroom_coursework_delete", {
|
|
31600
|
+
description: "Delete a coursework item.",
|
|
31601
|
+
annotations: { destructiveHint: true },
|
|
31602
|
+
inputSchema: {
|
|
31603
|
+
courseId: external_exports.string().describe("Course ID"),
|
|
31604
|
+
courseworkId: external_exports.string().describe("Coursework ID"),
|
|
31605
|
+
account: accountParam
|
|
31606
|
+
}
|
|
31607
|
+
}, async ({ courseId, courseworkId, account }) => {
|
|
31608
|
+
return runOrDiagnose(["classroom", "coursework", "delete", courseId, courseworkId], { account });
|
|
31609
|
+
});
|
|
31610
|
+
server2.registerTool("gog_classroom_announcements_update", {
|
|
31611
|
+
description: "Update an existing announcement.",
|
|
31612
|
+
annotations: { destructiveHint: true },
|
|
31613
|
+
inputSchema: {
|
|
31614
|
+
courseId: external_exports.string().describe("Course ID"),
|
|
31615
|
+
announcementId: external_exports.string().describe("Announcement ID"),
|
|
31616
|
+
text: external_exports.string().optional().describe("New text"),
|
|
31617
|
+
state: workState.optional().describe("State"),
|
|
31618
|
+
scheduled: external_exports.string().optional().describe("Scheduled publish time"),
|
|
31619
|
+
account: accountParam
|
|
31620
|
+
}
|
|
31621
|
+
}, async ({ courseId, announcementId, text, state, scheduled, account }) => {
|
|
31622
|
+
const args = ["classroom", "announcements", "update", courseId, announcementId];
|
|
31623
|
+
if (text) args.push(`--text=${text}`);
|
|
31624
|
+
if (state) args.push(`--state=${state}`);
|
|
31625
|
+
if (scheduled) args.push(`--scheduled=${scheduled}`);
|
|
31626
|
+
return runOrDiagnose(args, { account });
|
|
31627
|
+
});
|
|
31628
|
+
server2.registerTool("gog_classroom_announcements_delete", {
|
|
31629
|
+
description: "Delete an announcement.",
|
|
31630
|
+
annotations: { destructiveHint: true },
|
|
31631
|
+
inputSchema: {
|
|
31632
|
+
courseId: external_exports.string().describe("Course ID"),
|
|
31633
|
+
announcementId: external_exports.string().describe("Announcement ID"),
|
|
31634
|
+
account: accountParam
|
|
31635
|
+
}
|
|
31636
|
+
}, async ({ courseId, announcementId, account }) => {
|
|
31637
|
+
return runOrDiagnose(["classroom", "announcements", "delete", courseId, announcementId], { account });
|
|
31638
|
+
});
|
|
31639
|
+
server2.registerTool("gog_classroom_topics_create", {
|
|
31640
|
+
description: "Create a topic in a Google Classroom course.",
|
|
31641
|
+
inputSchema: {
|
|
31642
|
+
courseId: external_exports.string().describe("Course ID"),
|
|
31643
|
+
name: external_exports.string().describe("Topic name"),
|
|
31644
|
+
account: accountParam
|
|
31645
|
+
}
|
|
31646
|
+
}, async ({ courseId, name, account }) => {
|
|
31647
|
+
return runOrDiagnose(["classroom", "topics", "create", courseId, `--name=${name}`], { account });
|
|
31648
|
+
});
|
|
31649
|
+
server2.registerTool("gog_classroom_topics_update", {
|
|
31650
|
+
description: "Rename an existing topic.",
|
|
31651
|
+
annotations: { destructiveHint: true },
|
|
31652
|
+
inputSchema: {
|
|
31653
|
+
courseId: external_exports.string().describe("Course ID"),
|
|
31654
|
+
topicId: external_exports.string().describe("Topic ID"),
|
|
31655
|
+
name: external_exports.string().describe("New topic name"),
|
|
31656
|
+
account: accountParam
|
|
31657
|
+
}
|
|
31658
|
+
}, async ({ courseId, topicId, name, account }) => {
|
|
31659
|
+
return runOrDiagnose(["classroom", "topics", "update", courseId, topicId, `--name=${name}`], { account });
|
|
31660
|
+
});
|
|
31661
|
+
server2.registerTool("gog_classroom_topics_delete", {
|
|
31662
|
+
description: "Delete a topic.",
|
|
31663
|
+
annotations: { destructiveHint: true },
|
|
31664
|
+
inputSchema: {
|
|
31665
|
+
courseId: external_exports.string().describe("Course ID"),
|
|
31666
|
+
topicId: external_exports.string().describe("Topic ID"),
|
|
31667
|
+
account: accountParam
|
|
31668
|
+
}
|
|
31669
|
+
}, async ({ courseId, topicId, account }) => {
|
|
31670
|
+
return runOrDiagnose(["classroom", "topics", "delete", courseId, topicId], { account });
|
|
31671
|
+
});
|
|
31672
|
+
server2.registerTool("gog_classroom_invitations_create", {
|
|
31673
|
+
description: "Create an invitation to a Google Classroom course.",
|
|
31674
|
+
inputSchema: {
|
|
31675
|
+
courseId: external_exports.string().describe("Course ID"),
|
|
31676
|
+
userId: external_exports.string().describe("User ID to invite"),
|
|
31677
|
+
role: external_exports.enum(["STUDENT", "TEACHER", "OWNER"]).describe("Role for the invited user"),
|
|
31678
|
+
account: accountParam
|
|
31679
|
+
}
|
|
31680
|
+
}, async ({ courseId, userId, role, account }) => {
|
|
31681
|
+
return runOrDiagnose(["classroom", "invitations", "create", courseId, userId, `--role=${role}`], { account });
|
|
31682
|
+
});
|
|
31683
|
+
server2.registerTool("gog_classroom_invitations_delete", {
|
|
31684
|
+
description: "Delete (revoke) a Google Classroom invitation.",
|
|
31685
|
+
annotations: { destructiveHint: true },
|
|
31686
|
+
inputSchema: {
|
|
31687
|
+
invitationId: external_exports.string().describe("Invitation ID"),
|
|
31688
|
+
account: accountParam
|
|
31689
|
+
}
|
|
31690
|
+
}, async ({ invitationId, account }) => {
|
|
31691
|
+
return runOrDiagnose(["classroom", "invitations", "delete", invitationId], { account });
|
|
31692
|
+
});
|
|
31692
31693
|
}
|
|
31693
31694
|
|
|
31694
31695
|
// 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.7",
|
|
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.7",
|
|
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
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
"source": "github",
|
|
8
8
|
"subfolder": "packages/gogcli-mcp-classroom"
|
|
9
9
|
},
|
|
10
|
-
"version": "2.0.
|
|
10
|
+
"version": "2.0.7",
|
|
11
11
|
"packages": [
|
|
12
12
|
{
|
|
13
13
|
"registryType": "npm",
|
|
14
14
|
"identifier": "gogcli-mcp-classroom",
|
|
15
|
-
"version": "2.0.
|
|
15
|
+
"version": "2.0.7",
|
|
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
|
});
|