mcp-classroom 0.1.0__tar.gz

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.
@@ -0,0 +1,474 @@
1
+ Metadata-Version: 2.4
2
+ Name: mcp-classroom
3
+ Version: 0.1.0
4
+ Summary: A stateless MCP server for Google Classroom — read courses, grade submissions, and auto-submit assignments.
5
+ Author-email: Muhammad Zain <zainchoudery786@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/zainchoudery786/mcp-classroom
8
+ Project-URL: Repository, https://github.com/zainchoudery786/mcp-classroom
9
+ Project-URL: Bug Tracker, https://github.com/zainchoudery786/mcp-classroom/issues
10
+ Keywords: mcp,google-classroom,llm,ai,education,model-context-protocol
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Education
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Operating System :: OS Independent
19
+ Classifier: Topic :: Education
20
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
21
+ Requires-Python: >=3.10
22
+ Description-Content-Type: text/markdown
23
+ Requires-Dist: mcp>=1.0.0
24
+ Requires-Dist: pydantic-settings>=2.2.0
25
+ Requires-Dist: google-auth>=2.28.0
26
+ Requires-Dist: google-auth-oauthlib>=1.2.0
27
+ Requires-Dist: google-api-python-client>=2.122.0
28
+
29
+ # 🎓 MCP Classroom
30
+
31
+ > A stateless, production-ready **[Model Context Protocol](https://modelcontextprotocol.io)** server for Google Classroom.
32
+ > Connect any AI assistant directly to your courses — read rosters and assignments, auto-solve and submit student work, grade submissions, and post polished announcements.
33
+
34
+ [![PyPI](https://img.shields.io/badge/PyPI-v0.1.0-blue?logo=pypi&logoColor=white)](https://pypi.org/project/mcp-classroom/) [![Python](https://img.shields.io/badge/Python-3.10%2B-blue?logo=python&logoColor=white)](https://pypi.org/project/mcp-classroom/) [![License](https://img.shields.io/badge/License-MIT-green?logo=opensourceinitiative&logoColor=white)](https://opensource.org/licenses/MIT) ![MCP](https://img.shields.io/badge/MCP-Compatible-purple?logo=anthropic&logoColor=white)
35
+
36
+
37
+ ---
38
+
39
+ ## ✨ What It Does
40
+
41
+ | | |
42
+ |---|---|
43
+ | 📚 **Read** | Courses, student & teacher rosters, assignments, submissions, announcements |
44
+ | 📝 **Create** | Assignments and announcements — with optional AI content polishing |
45
+ | 🤖 **Solve & Submit** | Agents can read, solve, and autonomously turn in assignments |
46
+ | 🏆 **Grade** | Set draft and assigned grades on student submissions |
47
+ | 💬 **Prompts** | Built-in MCP prompts for solving, grading, and progress analysis |
48
+ | 📂 **Resources** | Direct context access without tool calls |
49
+ | 🔐 **Zero Setup Auth** | Pre-configured desktop OAuth — no developer console needed |
50
+
51
+ ---
52
+
53
+ ## 📦 Installation
54
+
55
+ ```bash
56
+ pip install mcp-classroom
57
+ ```
58
+
59
+ Or run directly without installing (recommended for MCP clients):
60
+
61
+ ```bash
62
+ uvx mcp-classroom
63
+ ```
64
+
65
+ > **Requires Python 3.10+**
66
+
67
+ ---
68
+
69
+ ## 🔐 Authentication
70
+
71
+ On first run, a browser window opens asking you to sign in with Google and grant Classroom permissions. Credentials are cached in `token.json` — you won't be prompted again until the token expires.
72
+
73
+ **No developer console setup required.** Pre-configured desktop OAuth ships with the package.
74
+
75
+ ---
76
+
77
+ ## ⚙️ Optional: LLM Integration
78
+
79
+ Some tools optionally use an LLM to polish content (e.g. rewriting assignment descriptions, adjusting announcement tone). Any **OpenAI-compatible API** is supported.
80
+
81
+ Set these environment variables to enable it:
82
+
83
+ | Variable | Description | Example |
84
+ |---|---|---|
85
+ | `LLM_API_KEY` | Your LLM provider API key | `sk-...` |
86
+ | `LLM_BASE_URL` | Base URL of the OpenAI-compatible endpoint | `https://api.openai.com/v1` |
87
+ | `LLM_MODEL_ID` | Model identifier | `gpt-4o` |
88
+
89
+ > If these are not set the server runs in **standard mode** — all tools still work, content polishing is just skipped.
90
+
91
+ ---
92
+
93
+ ## 🖥️ Client Setup
94
+
95
+ <details>
96
+ <summary><b>Claude Desktop</b></summary>
97
+
98
+ Edit your `claude_desktop_config.json`:
99
+ - **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
100
+ - **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
101
+
102
+ ```json
103
+ {
104
+ "mcpServers": {
105
+ "google-classroom": {
106
+ "command": "uvx",
107
+ "args": ["mcp-classroom"],
108
+ "env": {
109
+ "LLM_API_KEY": "YOUR_API_KEY",
110
+ "LLM_BASE_URL": "https://api.openai.com/v1",
111
+ "LLM_MODEL_ID": "gpt-4o"
112
+ }
113
+ }
114
+ }
115
+ }
116
+ ```
117
+
118
+ </details>
119
+
120
+ <details>
121
+ <summary><b>Cursor</b></summary>
122
+
123
+ Add to `~/.cursor/mcp.json` (or via **Cursor Settings → Features → MCP → + Add New MCP Server**):
124
+
125
+ ```json
126
+ {
127
+ "mcpServers": {
128
+ "google-classroom": {
129
+ "command": "uvx",
130
+ "args": ["mcp-classroom"],
131
+ "env": {
132
+ "LLM_API_KEY": "YOUR_API_KEY",
133
+ "LLM_BASE_URL": "https://api.openai.com/v1",
134
+ "LLM_MODEL_ID": "gpt-4o"
135
+ }
136
+ }
137
+ }
138
+ }
139
+ ```
140
+
141
+ </details>
142
+
143
+ <details>
144
+ <summary><b>Claude Code (CLI)</b></summary>
145
+
146
+ **Without LLM:**
147
+ ```bash
148
+ claude mcp add uvx -- mcp-classroom
149
+ ```
150
+
151
+ **With LLM integration:**
152
+ ```bash
153
+ claude mcp add uvx \
154
+ --env LLM_API_KEY=YOUR_API_KEY \
155
+ --env LLM_BASE_URL=https://api.openai.com/v1 \
156
+ --env LLM_MODEL_ID=gpt-4o \
157
+ -- mcp-classroom
158
+ ```
159
+
160
+ </details>
161
+
162
+ <details>
163
+ <summary><b>VS Code — GitHub Copilot</b></summary>
164
+
165
+ Add to `.vscode/mcp.json` in your workspace (or user settings):
166
+
167
+ ```json
168
+ {
169
+ "servers": {
170
+ "google-classroom": {
171
+ "type": "stdio",
172
+ "command": "uvx",
173
+ "args": ["mcp-classroom"],
174
+ "env": {
175
+ "LLM_API_KEY": "YOUR_API_KEY",
176
+ "LLM_BASE_URL": "https://api.openai.com/v1",
177
+ "LLM_MODEL_ID": "gpt-4o"
178
+ }
179
+ }
180
+ }
181
+ }
182
+ ```
183
+
184
+ </details>
185
+
186
+ <details>
187
+ <summary><b>VS Code — Continue Extension</b></summary>
188
+
189
+ Add to `~/.continue/config.json`:
190
+
191
+ ```json
192
+ {
193
+ "mcpServers": [
194
+ {
195
+ "name": "google-classroom",
196
+ "command": "uvx",
197
+ "args": ["mcp-classroom"],
198
+ "env": {
199
+ "LLM_API_KEY": "YOUR_API_KEY",
200
+ "LLM_BASE_URL": "https://api.openai.com/v1",
201
+ "LLM_MODEL_ID": "gpt-4o"
202
+ }
203
+ }
204
+ ]
205
+ }
206
+ ```
207
+
208
+ </details>
209
+
210
+ <details>
211
+ <summary><b>Windsurf</b></summary>
212
+
213
+ Edit `~/.codeium/windsurf/mcp_config.json`:
214
+
215
+ ```json
216
+ {
217
+ "mcpServers": {
218
+ "google-classroom": {
219
+ "command": "uvx",
220
+ "args": ["mcp-classroom"],
221
+ "env": {
222
+ "LLM_API_KEY": "YOUR_API_KEY",
223
+ "LLM_BASE_URL": "https://api.openai.com/v1",
224
+ "LLM_MODEL_ID": "gpt-4o"
225
+ }
226
+ }
227
+ }
228
+ }
229
+ ```
230
+
231
+ </details>
232
+
233
+ <details>
234
+ <summary><b>Antigravity</b></summary>
235
+
236
+ Go to **Settings → MCP Servers → Add Server** and paste:
237
+
238
+ ```json
239
+ {
240
+ "mcpServers": {
241
+ "google-classroom": {
242
+ "command": "uvx",
243
+ "args": ["mcp-classroom"],
244
+ "env": {
245
+ "LLM_API_KEY": "YOUR_API_KEY",
246
+ "LLM_BASE_URL": "https://api.openai.com/v1",
247
+ "LLM_MODEL_ID": "gpt-4o"
248
+ }
249
+ }
250
+ }
251
+ }
252
+ ```
253
+
254
+ </details>
255
+
256
+ ---
257
+
258
+ ## 🛠️ Tools
259
+
260
+ ### Courses
261
+
262
+ #### `list_google_courses`
263
+ Lists all active Google Classroom courses for the authenticated user.
264
+
265
+ **Returns:** Course ID, name, section, description, and link.
266
+ **Arguments:** None
267
+ **Constraints:** None.
268
+
269
+ ---
270
+
271
+ ### Roster
272
+
273
+ #### `list_google_students`
274
+ Lists all students enrolled in a course.
275
+
276
+ **Returns:** User ID, full name, email address.
277
+
278
+ | Argument | Type | Description |
279
+ |---|---|---|
280
+ | `course_id` | `string` | ID of the course |
281
+
282
+ #### `list_google_teachers`
283
+ Lists all teachers and co-teachers of a course.
284
+
285
+ **Returns:** User ID, full name, email address.
286
+
287
+ | Argument | Type | Description |
288
+ |---|---|---|
289
+ | `course_id` | `string` | ID of the course |
290
+
291
+ ---
292
+
293
+ ### Assignments
294
+
295
+ #### `list_google_coursework`
296
+ Lists every assignment in a course with full details and the authenticated user's submission state.
297
+
298
+ **Returns:** ID, title, description, max points, due date, link, submission state (`NEW` / `CREATED` / `TURNED_IN` / `RETURNED`), submission ID, and a pre-built `solving_prompt` ready to feed into any LLM.
299
+
300
+ | Argument | Type | Description |
301
+ |---|---|---|
302
+ | `course_id` | `string` | ID of the course |
303
+
304
+ #### `list_upcoming_assignments`
305
+ Same as above but filtered to **pending-only** work, sorted by closest due date first. Skips anything already `TURNED_IN` or `RETURNED`.
306
+
307
+ | Argument | Type | Description |
308
+ |---|---|---|
309
+ | `course_id` | `string` | ID of the course |
310
+
311
+ #### `create_google_coursework`
312
+ Creates and publishes a new assignment in a course.
313
+
314
+ **Returns:** Success status, new assignment ID, direct link.
315
+ **LLM Enhancement:** If `LLM_API_KEY` is set, the description is automatically restructured with headings, bullet points, a grading rubric, and a due date reminder.
316
+
317
+ | Argument | Type | Required | Description |
318
+ |---|---|---|---|
319
+ | `course_id` | `string` | ✅ | ID of the course |
320
+ | `title` | `string` | ✅ | Assignment title |
321
+ | `description` | `string` | ❌ | Assignment instructions |
322
+ | `max_points` | `integer` | ❌ | Maximum grade (default: `100`) |
323
+ | `due_date` | `string` | ❌ | `YYYY-MM-DD` |
324
+ | `due_time` | `string` | ❌ | `HH:MM` (24-hour) |
325
+
326
+ > ⛔ **Teacher accounts only.** Students receive `403 Forbidden`.
327
+ > ⚠️ Only assignments created through this tool can be graded via `grade_google_submission`.
328
+
329
+ ---
330
+
331
+ ### Submissions
332
+
333
+ #### `list_google_submissions`
334
+ Lists every student's submission record for an assignment.
335
+
336
+ **Returns:** Submission ID, user ID, state, draft grade, assigned grade, submitted text (short answers), and link.
337
+
338
+ | Argument | Type | Description |
339
+ |---|---|---|
340
+ | `course_id` | `string` | ID of the course |
341
+ | `coursework_id` | `string` | ID of the assignment |
342
+
343
+ > Students see only their own submission. Teachers see all.
344
+
345
+ #### `submit_student_assignment`
346
+ Attaches an answer and turns in an assignment on behalf of the authenticated student.
347
+
348
+ Supports two submission types:
349
+ - **`text_answer`** — for `SHORT_ANSWER_QUESTION` coursework
350
+ - **`attachment_url`** — for `ASSIGNMENT` coursework (GitHub link, Google Doc, etc.)
351
+
352
+ The tool automatically calls `turnIn` after attaching the answer.
353
+
354
+ | Argument | Type | Required | Description |
355
+ |---|---|---|---|
356
+ | `course_id` | `string` | ✅ | ID of the course |
357
+ | `coursework_id` | `string` | ✅ | ID of the assignment |
358
+ | `text_answer` | `string` | ❌ | Text answer (SHORT_ANSWER_QUESTION only) |
359
+ | `attachment_url` | `string` | ❌ | URL to attach (ASSIGNMENT type only) |
360
+
361
+ > ⛔ **Student accounts only.** Teacher accounts have no submission record.
362
+ > ⛔ **Only works on assignments created by this server.** Assignments made in the Classroom UI return `403 @ProjectPermissionDenied` — this is a permanent Google API restriction.
363
+
364
+ #### `grade_google_submission`
365
+ Sets a draft and/or assigned grade on a student's submission.
366
+
367
+ **Returns:** Updated submission with confirmed grade values.
368
+
369
+ | Argument | Type | Required | Description |
370
+ |---|---|---|---|
371
+ | `course_id` | `string` | ✅ | ID of the course |
372
+ | `coursework_id` | `string` | ✅ | ID of the assignment |
373
+ | `submission_id` | `string` | ✅ | ID of the student's submission |
374
+ | `draft_grade` | `float` | ✅ | Grade visible only to the teacher |
375
+ | `assigned_grade` | `float` | ❌ | Grade returned to the student |
376
+
377
+ > ⛔ **Teacher accounts only.**
378
+ > ⛔ **Only works on assignments created by this server.** The Google Classroom API permanently restricts `patch` to the same Developer Console project that created the coursework — no scope or permission can override this.
379
+
380
+ ---
381
+
382
+ ### Announcements
383
+
384
+ #### `list_google_announcements`
385
+ Lists all announcements from the course stream.
386
+
387
+ **Returns:** ID, full text, creation timestamp, link.
388
+
389
+ | Argument | Type | Description |
390
+ |---|---|---|
391
+ | `course_id` | `string` | ID of the course |
392
+
393
+ #### `create_google_announcement`
394
+ Posts a new announcement to the course stream.
395
+
396
+ **Returns:** Success status, announcement ID, link.
397
+ **LLM Enhancement:** If `LLM_API_KEY` is set, the text is rewritten in the requested tone before posting.
398
+
399
+ | Argument | Type | Required | Description |
400
+ |---|---|---|---|
401
+ | `course_id` | `string` | ✅ | ID of the course |
402
+ | `text` | `string` | ✅ | Announcement content |
403
+ | `tone` | `string` | ❌ | e.g. `professional`, `friendly`, `urgent` |
404
+
405
+ > ⛔ **Teacher accounts only.**
406
+
407
+ ---
408
+
409
+ ## 📂 Resources
410
+
411
+ Query structured Classroom data directly as context — no tool call needed.
412
+
413
+ | URI | Description |
414
+ |---|---|
415
+ | `googleclassroom://courses` | All active courses |
416
+ | `googleclassroom://course/{course_id}/coursework` | All assignments in a course |
417
+ | `googleclassroom://course/{course_id}/announcements` | All announcements in a course |
418
+ | `googleclassroom://course/{course_id}/roster` | Students and teachers in a course |
419
+ | `googleclassroom://course/{course_id}/upcoming` | Pending assignments sorted by due date |
420
+
421
+ ---
422
+
423
+ ## 💬 Prompts
424
+
425
+ Built-in MCP Prompts that guide an AI through complex multi-step Classroom workflows.
426
+
427
+ **`solve_assignment_prompt`**
428
+ Prepares an AI to write a complete solution to an assignment. Includes title, max points, due date, instructions, and output format guidance. Every assignment returned by `list_google_coursework` already includes a pre-built version of this prompt in the `solving_prompt` field.
429
+
430
+ **`grade_submission_prompt`**
431
+ Guides an AI through evaluating submitted work against the assignment rubric. Pass alongside submission data from `list_google_submissions` to get a suggested grade and feedback before calling `grade_google_submission`.
432
+
433
+ **`analyze_student_progress_prompt`**
434
+ Helps an AI review a student's grades across all assignments and produce a personalized progress report or study plan.
435
+
436
+ ---
437
+
438
+ ## 🔒 Constraints at a Glance
439
+
440
+ | Tool | Requires Teacher | Requires Student | Created by This Server |
441
+ |---|:---:|:---:|:---:|
442
+ | `list_google_courses` | | | |
443
+ | `list_google_students` | | | |
444
+ | `list_google_teachers` | | | |
445
+ | `list_google_coursework` | | | |
446
+ | `list_upcoming_assignments` | | | |
447
+ | `list_google_submissions` | | | |
448
+ | `list_google_announcements` | | | |
449
+ | `create_google_coursework` | ✅ | | |
450
+ | `create_google_announcement` | ✅ | | |
451
+ | `submit_student_assignment` | | ✅ | ✅ Required |
452
+ | `grade_google_submission` | ✅ | | ✅ Required |
453
+
454
+ > **Why "Created by This Server"?**
455
+ > Google Classroom enforces that `turnIn`, `modifyAttachments`, and grade `patch` can only be called by the same Developer Console project that created the assignment. This is a hard platform rule — it cannot be bypassed with any scope or permission.
456
+
457
+ ---
458
+
459
+ ## 🗂️ OAuth Scopes
460
+
461
+ | Scope | Purpose |
462
+ |---|---|
463
+ | `classroom.courses.readonly` | Read course list |
464
+ | `classroom.coursework.students` | Read/write assignments and grade submissions (teacher) |
465
+ | `classroom.coursework.me` | Read/write own submissions, turn in work (student) |
466
+ | `classroom.rosters.readonly` | Read student and teacher rosters |
467
+ | `classroom.announcements` | Read and post announcements |
468
+ | `classroom.profile.emails` | Read user email addresses |
469
+
470
+ ---
471
+
472
+ ## 📄 License
473
+
474
+ MIT © [Muhammad Zain](https://github.com/zainf2327)