gogcli-mcp-classroom 2.29.1 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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.29.1",
6
+ "version": "3.0.0",
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/mint.yaml CHANGED
@@ -14,7 +14,7 @@ env:
14
14
  help: >-
15
15
  Google OAuth client id. NOTE: on the local-spawn path the child `gog`
16
16
  receives a sanitized env — runner.ts drops GOG_ACCESS_TOKEN and every
17
- *_TOKEN / *_SECRET / *_API_KEY / *_PRIVATE_KEY variable — so the CLI
17
+ *_TOKEN / *_SECRET / *_KEY / *_CREDENTIALS variable — so the CLI
18
18
  authenticates from its own stored credentials under $HOME (see
19
19
  state.dataDir), not from these variables being passed through.
20
20
  - name: GOG_CLIENT_SECRET
@@ -87,7 +87,7 @@ dependencies:
87
87
  # nine pins too.
88
88
  - kind: github-release
89
89
  repo: openclaw/gogcli
90
- tag: v0.39.1
90
+ tag: v0.40.0
91
91
  asset: "gogcli_*_linux_amd64.tar.gz"
92
92
  bin: [gog]
93
93
  state:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gogcli-mcp-classroom",
3
- "version": "2.29.1",
3
+ "version": "3.0.0",
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>",
@@ -24,9 +24,9 @@
24
24
  "test:coverage": "vitest run --coverage"
25
25
  },
26
26
  "dependencies": {
27
- "@chrischall/mcp-utils": "^0.23.0",
28
- "@modelcontextprotocol/sdk": "^1.30.0",
29
- "zod": "^4.5.4"
27
+ "@chrischall/mcp-utils": "^0.28.0",
28
+ "@modelcontextprotocol/server": "^2.0.0",
29
+ "zod": "^4.6.1"
30
30
  },
31
31
  "license": "MIT",
32
32
  "keywords": [
package/server.json CHANGED
@@ -7,12 +7,12 @@
7
7
  "source": "github",
8
8
  "subfolder": "packages/gogcli-mcp-classroom"
9
9
  },
10
- "version": "2.29.1",
10
+ "version": "3.0.0",
11
11
  "packages": [
12
12
  {
13
13
  "registryType": "npm",
14
14
  "identifier": "gogcli-mcp-classroom",
15
- "version": "2.29.1",
15
+ "version": "3.0.0",
16
16
  "transport": {
17
17
  "type": "stdio"
18
18
  },
@@ -1,4 +1,4 @@
1
- import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
1
+ import { McpServer } from '@modelcontextprotocol/server';
2
2
  import { z } from 'zod';
3
3
  import { accountParam, runOrDiagnose } from '../../../gogcli-mcp/src/lib.js';
4
4
 
@@ -34,11 +34,11 @@ const courseworkSharedFields = {
34
34
  export function registerExtraClassroomTools(server: McpServer): void {
35
35
  server.registerTool('gog_classroom_courses_create', {
36
36
  description: 'Create a new Google Classroom course.',
37
- inputSchema: {
37
+ inputSchema: z.object({
38
38
  name: z.string().describe('Course name'),
39
39
  ...courseSharedFields,
40
40
  account: accountParam,
41
- },
41
+ }),
42
42
  }, async ({ name, owner, section, descriptionHeading, description, room, state, account }) => {
43
43
  const args = ['classroom', 'courses', 'create', `--name=${name}`];
44
44
  if (owner) args.push(`--owner=${owner}`);
@@ -53,12 +53,12 @@ export function registerExtraClassroomTools(server: McpServer): void {
53
53
  server.registerTool('gog_classroom_courses_update', {
54
54
  description: 'Update an existing Google Classroom course.',
55
55
  annotations: { destructiveHint: true },
56
- inputSchema: {
56
+ inputSchema: z.object({
57
57
  courseId: z.string().describe('Course ID'),
58
58
  name: z.string().optional().describe('Course name'),
59
59
  ...courseSharedFields,
60
60
  account: accountParam,
61
- },
61
+ }),
62
62
  }, async ({ courseId, name, owner, section, descriptionHeading, description, room, state, account }) => {
63
63
  const args = ['classroom', 'courses', 'update', courseId];
64
64
  if (name) args.push(`--name=${name}`);
@@ -74,10 +74,10 @@ export function registerExtraClassroomTools(server: McpServer): void {
74
74
  server.registerTool('gog_classroom_courses_delete', {
75
75
  description: 'Delete a Google Classroom course.',
76
76
  annotations: { destructiveHint: true },
77
- inputSchema: {
77
+ inputSchema: z.object({
78
78
  courseId: z.string().describe('Course ID'),
79
79
  account: accountParam,
80
- },
80
+ }),
81
81
  }, async ({ courseId, account }) => {
82
82
  return runOrDiagnose(['classroom', 'courses', 'delete', courseId, '--force'], { account }); // gog gates this op; without --force the runner's --no-input makes it refuse
83
83
  });
@@ -85,32 +85,32 @@ export function registerExtraClassroomTools(server: McpServer): void {
85
85
  server.registerTool('gog_classroom_courses_archive', {
86
86
  description: 'Archive a Google Classroom course.',
87
87
  annotations: { destructiveHint: true },
88
- inputSchema: {
88
+ inputSchema: z.object({
89
89
  courseId: z.string().describe('Course ID'),
90
90
  account: accountParam,
91
- },
91
+ }),
92
92
  }, async ({ courseId, account }) => {
93
93
  return runOrDiagnose(['classroom', 'courses', 'archive', courseId], { account });
94
94
  });
95
95
 
96
96
  server.registerTool('gog_classroom_courses_unarchive', {
97
97
  description: 'Unarchive a Google Classroom course (restore to ACTIVE).',
98
- inputSchema: {
98
+ inputSchema: z.object({
99
99
  courseId: z.string().describe('Course ID'),
100
100
  account: accountParam,
101
- },
101
+ }),
102
102
  }, async ({ courseId, account }) => {
103
103
  return runOrDiagnose(['classroom', 'courses', 'unarchive', courseId], { account });
104
104
  });
105
105
 
106
106
  server.registerTool('gog_classroom_students_add', {
107
107
  description: 'Add a student to a Google Classroom course.',
108
- inputSchema: {
108
+ inputSchema: z.object({
109
109
  courseId: z.string().describe('Course ID'),
110
110
  userId: z.string().describe('Student user ID (or "me")'),
111
111
  enrollmentCode: z.string().optional().describe('Enrollment code (required if adding self via code)'),
112
112
  account: accountParam,
113
- },
113
+ }),
114
114
  }, async ({ courseId, userId, enrollmentCode, account }) => {
115
115
  const args = ['classroom', 'students', 'add', courseId, userId];
116
116
  if (enrollmentCode) args.push(`--enrollment-code=${enrollmentCode}`);
@@ -120,22 +120,22 @@ export function registerExtraClassroomTools(server: McpServer): void {
120
120
  server.registerTool('gog_classroom_students_remove', {
121
121
  description: 'Remove a student from a Google Classroom course.',
122
122
  annotations: { destructiveHint: true },
123
- inputSchema: {
123
+ inputSchema: z.object({
124
124
  courseId: z.string().describe('Course ID'),
125
125
  userId: z.string().describe('Student user ID'),
126
126
  account: accountParam,
127
- },
127
+ }),
128
128
  }, async ({ courseId, userId, account }) => {
129
129
  return runOrDiagnose(['classroom', 'students', 'remove', courseId, userId, '--force'], { account }); // gog gates this op; without --force the runner's --no-input makes it refuse
130
130
  });
131
131
 
132
132
  server.registerTool('gog_classroom_teachers_add', {
133
133
  description: 'Add a teacher to a Google Classroom course.',
134
- inputSchema: {
134
+ inputSchema: z.object({
135
135
  courseId: z.string().describe('Course ID'),
136
136
  userId: z.string().describe('Teacher user ID'),
137
137
  account: accountParam,
138
- },
138
+ }),
139
139
  }, async ({ courseId, userId, account }) => {
140
140
  return runOrDiagnose(['classroom', 'teachers', 'add', courseId, userId], { account });
141
141
  });
@@ -143,23 +143,23 @@ export function registerExtraClassroomTools(server: McpServer): void {
143
143
  server.registerTool('gog_classroom_teachers_remove', {
144
144
  description: 'Remove a teacher from a Google Classroom course.',
145
145
  annotations: { destructiveHint: true },
146
- inputSchema: {
146
+ inputSchema: z.object({
147
147
  courseId: z.string().describe('Course ID'),
148
148
  userId: z.string().describe('Teacher user ID'),
149
149
  account: accountParam,
150
- },
150
+ }),
151
151
  }, async ({ courseId, userId, account }) => {
152
152
  return runOrDiagnose(['classroom', 'teachers', 'remove', courseId, userId, '--force'], { account }); // gog gates this op; without --force the runner's --no-input makes it refuse
153
153
  });
154
154
 
155
155
  server.registerTool('gog_classroom_coursework_create', {
156
156
  description: 'Create a new coursework item (assignment, question, etc.) in a course.',
157
- inputSchema: {
157
+ inputSchema: z.object({
158
158
  courseId: z.string().describe('Course ID'),
159
159
  title: z.string().describe('Coursework title'),
160
160
  ...courseworkSharedFields,
161
161
  account: accountParam,
162
- },
162
+ }),
163
163
  }, async ({ courseId, title, description, type, state, maxPoints, due, dueDate, dueTime, scheduled, topic, account }) => {
164
164
  const args = ['classroom', 'coursework', 'create', courseId, `--title=${title}`];
165
165
  if (description) args.push(`--description=${description}`);
@@ -177,13 +177,13 @@ export function registerExtraClassroomTools(server: McpServer): void {
177
177
  server.registerTool('gog_classroom_coursework_update', {
178
178
  description: 'Update an existing coursework item.',
179
179
  annotations: { destructiveHint: true },
180
- inputSchema: {
180
+ inputSchema: z.object({
181
181
  courseId: z.string().describe('Course ID'),
182
182
  courseworkId: z.string().describe('Coursework ID'),
183
183
  title: z.string().optional().describe('New title'),
184
184
  ...courseworkSharedFields,
185
185
  account: accountParam,
186
- },
186
+ }),
187
187
  }, async ({ courseId, courseworkId, title, description, type, state, maxPoints, due, dueDate, dueTime, scheduled, topic, account }) => {
188
188
  const args = ['classroom', 'coursework', 'update', courseId, courseworkId];
189
189
  if (title) args.push(`--title=${title}`);
@@ -202,11 +202,11 @@ export function registerExtraClassroomTools(server: McpServer): void {
202
202
  server.registerTool('gog_classroom_coursework_delete', {
203
203
  description: 'Delete a coursework item.',
204
204
  annotations: { destructiveHint: true },
205
- inputSchema: {
205
+ inputSchema: z.object({
206
206
  courseId: z.string().describe('Course ID'),
207
207
  courseworkId: z.string().describe('Coursework ID'),
208
208
  account: accountParam,
209
- },
209
+ }),
210
210
  }, async ({ courseId, courseworkId, account }) => {
211
211
  return runOrDiagnose(['classroom', 'coursework', 'delete', courseId, courseworkId, '--force'], { account }); // gog gates this op; without --force the runner's --no-input makes it refuse
212
212
  });
@@ -214,14 +214,14 @@ export function registerExtraClassroomTools(server: McpServer): void {
214
214
  server.registerTool('gog_classroom_announcements_update', {
215
215
  description: 'Update an existing announcement.',
216
216
  annotations: { destructiveHint: true },
217
- inputSchema: {
217
+ inputSchema: z.object({
218
218
  courseId: z.string().describe('Course ID'),
219
219
  announcementId: z.string().describe('Announcement ID'),
220
220
  text: z.string().optional().describe('New text'),
221
221
  state: workState.optional().describe('State'),
222
222
  scheduled: z.string().optional().describe('Scheduled publish time'),
223
223
  account: accountParam,
224
- },
224
+ }),
225
225
  }, async ({ courseId, announcementId, text, state, scheduled, account }) => {
226
226
  const args = ['classroom', 'announcements', 'update', courseId, announcementId];
227
227
  if (text) args.push(`--text=${text}`);
@@ -233,22 +233,22 @@ export function registerExtraClassroomTools(server: McpServer): void {
233
233
  server.registerTool('gog_classroom_announcements_delete', {
234
234
  description: 'Delete an announcement.',
235
235
  annotations: { destructiveHint: true },
236
- inputSchema: {
236
+ inputSchema: z.object({
237
237
  courseId: z.string().describe('Course ID'),
238
238
  announcementId: z.string().describe('Announcement ID'),
239
239
  account: accountParam,
240
- },
240
+ }),
241
241
  }, async ({ courseId, announcementId, account }) => {
242
242
  return runOrDiagnose(['classroom', 'announcements', 'delete', courseId, announcementId, '--force'], { account }); // gog gates this op; without --force the runner's --no-input makes it refuse
243
243
  });
244
244
 
245
245
  server.registerTool('gog_classroom_topics_create', {
246
246
  description: 'Create a topic in a Google Classroom course.',
247
- inputSchema: {
247
+ inputSchema: z.object({
248
248
  courseId: z.string().describe('Course ID'),
249
249
  name: z.string().describe('Topic name'),
250
250
  account: accountParam,
251
- },
251
+ }),
252
252
  }, async ({ courseId, name, account }) => {
253
253
  return runOrDiagnose(['classroom', 'topics', 'create', courseId, `--name=${name}`], { account });
254
254
  });
@@ -256,12 +256,12 @@ export function registerExtraClassroomTools(server: McpServer): void {
256
256
  server.registerTool('gog_classroom_topics_update', {
257
257
  description: 'Rename an existing topic.',
258
258
  annotations: { destructiveHint: true },
259
- inputSchema: {
259
+ inputSchema: z.object({
260
260
  courseId: z.string().describe('Course ID'),
261
261
  topicId: z.string().describe('Topic ID'),
262
262
  name: z.string().describe('New topic name'),
263
263
  account: accountParam,
264
- },
264
+ }),
265
265
  }, async ({ courseId, topicId, name, account }) => {
266
266
  return runOrDiagnose(['classroom', 'topics', 'update', courseId, topicId, `--name=${name}`], { account });
267
267
  });
@@ -269,23 +269,23 @@ export function registerExtraClassroomTools(server: McpServer): void {
269
269
  server.registerTool('gog_classroom_topics_delete', {
270
270
  description: 'Delete a topic.',
271
271
  annotations: { destructiveHint: true },
272
- inputSchema: {
272
+ inputSchema: z.object({
273
273
  courseId: z.string().describe('Course ID'),
274
274
  topicId: z.string().describe('Topic ID'),
275
275
  account: accountParam,
276
- },
276
+ }),
277
277
  }, async ({ courseId, topicId, account }) => {
278
278
  return runOrDiagnose(['classroom', 'topics', 'delete', courseId, topicId, '--force'], { account }); // gog gates this op; without --force the runner's --no-input makes it refuse
279
279
  });
280
280
 
281
281
  server.registerTool('gog_classroom_invitations_create', {
282
282
  description: 'Create an invitation to a Google Classroom course.',
283
- inputSchema: {
283
+ inputSchema: z.object({
284
284
  courseId: z.string().describe('Course ID'),
285
285
  userId: z.string().describe('User ID to invite'),
286
286
  role: z.enum(['STUDENT', 'TEACHER', 'OWNER']).describe('Role for the invited user'),
287
287
  account: accountParam,
288
- },
288
+ }),
289
289
  }, async ({ courseId, userId, role, account }) => {
290
290
  return runOrDiagnose(['classroom', 'invitations', 'create', courseId, userId, `--role=${role}`], { account });
291
291
  });
@@ -293,10 +293,10 @@ export function registerExtraClassroomTools(server: McpServer): void {
293
293
  server.registerTool('gog_classroom_invitations_delete', {
294
294
  description: 'Delete (revoke) a Google Classroom invitation.',
295
295
  annotations: { destructiveHint: true },
296
- inputSchema: {
296
+ inputSchema: z.object({
297
297
  invitationId: z.string().describe('Invitation ID'),
298
298
  account: accountParam,
299
- },
299
+ }),
300
300
  }, async ({ invitationId, account }) => {
301
301
  return runOrDiagnose(['classroom', 'invitations', 'delete', invitationId, '--force'], { account }); // gog gates this op; without --force the runner's --no-input makes it refuse
302
302
  });