Classroom MCP
by FW1201
README.md
<div align="center">
<img src="assets/logo.svg" width="120" alt="Classroom MCP">
# Classroom MCP
**讓 AI 助理直接操作你的 Google Classroom**
查誰沒交作業、列出學生名單、建立作業與公告——用講的就好。
[](https://deploy.workers.cloudflare.com/?url=https://github.com/FW1201/classroom-mcp)
[📖 完整安裝教學(給非工程師)](docs/INSTALL.zh-TW.md) ・
[🔧 疑難排解](docs/TROUBLESHOOTING.zh-TW.md)
</div>
---
## 這是什麼
一個部署在 Cloudflare Workers 上的**遠端 MCP 伺服器**。你自己部署一份、用自己的 Google 帳號授權,
資料只在你的 Google 帳號與你的 Worker 之間流動,不經過任何第三方。
```
你:「七年三班的段考複習還有誰沒交?」
AI:共 28 筆繳交紀錄,其中 5 位尚未繳交:
- 王小明:已繳交,分數 95
- 李小華:尚未繳交
- 張小美:已繳交(遲交),分數 88
...
```
## 能做什麼
| 工具 | 說明 |
|---|---|
| `list_courses` | 列出你任教的進行中課程 |
| `list_students` | 列出某門課的學生名單 |
| `list_coursework` | 列出某門課的所有作業 |
| `list_submissions` | 查看繳交狀況與分數(自動把學生 ID 對應成姓名) |
| `create_coursework` | 建立作業(**預設為草稿**,避免 AI 誤發布) |
| `create_announcement` | 發布課程公告 |
| `create_topic` | 建立主題分類 |
到期時間一律以**台北時間(UTC+8)**解讀,送給 Google 前自動轉成 UTC。
**刻意不做的事**:沒有 Google 雲端硬碟權限(讀不到學生繳交的檔案內容)、
沒有評分與發還作業的權限(改不了學生成績)。
## 支援哪些 AI 助理
這是標準的 MCP 伺服器(Streamable HTTP + OAuth 2.1),不綁特定廠商:
| 助理 | 怎麼接 |
|---|---|
| **Gemini Spark** | 設定 → Connected Apps → Custom apps for Spark |
| **Claude** | Settings → Connectors → Add custom connector |
| **Claude Code** | `claude mcp add --transport http classroom <你的網址>/mcp` |
| **ChatGPT** | Developer mode → Connectors |
| Cursor / VS Code / Windsurf / Zed | 各自的 MCP 設定填入網址 |
同一個網址可以同時給多個助理用(都會操作同一個 Classroom 帳號)。
> **Gemini Spark 的帳號限制**:Spark 目前只支援用**個人 Google 帳號**登入。
> 但這不影響你用學校帳號的 Classroom——授權那一步可以另外選帳號。
## 安裝
點上方的「Deploy to Cloudflare」按鈕,然後照著
**[完整安裝教學](docs/INSTALL.zh-TW.md)** 走,約 20 分鐘。
教學是為完全沒寫過程式的老師寫的,每一步都有連結可以直接點、有內容可以直接複製,
並且標出了實測時最容易卡住的幾個地方。
安裝流程大致是:
```
1. 點部署按鈕 → 得到你的專屬網址
2. 在 Google Cloud 開權限 → 步驟最多的一段,教學有逐步截圖式說明
3. 打開 <你的網址>/setup → 貼上憑證、設管理密碼
4. 把 <你的網址>/mcp 貼進 AI 助理 → 完成
```
## 為什麼要自己部署,不能大家共用一個?
Classroom 的學生名單與作業屬於 Google 的**敏感權限範圍**。
要做成公開共用的服務,開發者必須通過 Google 的 OAuth 審查與
[CASA 年度資安評估](https://appdefensealliance.dev/casa)——成本高昂,
而且所有人的資料都會經過同一台別人的伺服器。
改成每人自建:不需要任何審查、資料只留在自己手上、也沒有 100 人上限。
代價是要花約 20 分鐘做一次設定,之後就不用再碰。
## 安全性設計
- **憑證加密儲存**:Google refresh token 由 `@cloudflare/workers-oauth-provider`
加密後存在你自己的 Cloudflare KV,不會傳給任何第三方
- **擁有者鎖定**:第一個完成授權的 Google 帳號會被綁定,其他人即使知道網址也無法存取你的資料
- **草稿優先**:AI 建立的作業預設是草稿,需要你在 Classroom 手動確認發布
- **最小權限**:只申請實際用得到的 7 個 scope,每個都對照過官方文件
- **不留痕跡**:課程資料即時取得、用完即丟,不寫入任何資料庫或記錄檔
完整說明見部署後的 `<你的網址>/privacy`。
## 給開發者
```bash
npm install
npm test # 43 個測試
npm run typecheck
npx wrangler dev
```
**技術細節**
- **傳輸層**:Streamable HTTP,端點 `/mcp`
- **協定版本**:同時支援 2025-era(`initialize` 交握)與 2026-07-28(stateless)client,
由 [`@modelcontextprotocol/server`](https://www.npmjs.com/package/@modelcontextprotocol/server) v2 的 legacy fallback 自動處理
- **授權**:同一個 Worker 既是對 MCP client 的 OAuth 2.1 authorization server,
也是對 Google 的 OAuth client。支援 DCR、PKCE S256、RFC 9728 資源中繼資料、RFC 9207 `iss`
**專案結構**
```
src/
├── index.ts OAuthProvider 組裝(Worker 進入點)
├── auth-handler.ts /authorize、Google callback、首頁與法律頁路由
├── setup-page.ts /setup 設定精靈
├── legal-pages.ts 隱私權政策與服務條款
├── config.ts 設定儲存與管理密碼
├── state.ts HMAC 簽章的 OAuth state
├── errors.ts Google API 錯誤 → 可行動的中文訊息
├── google/ Google OAuth 與 Classroom REST client
└── mcp/ MCP handler、工具定義、台北時區換算
```
## 授權條款
MIT
---
<div align="center">
<sub>
本專案為獨立開發的開源工具,與 Google 沒有隸屬或背書關係。<br>
Google Classroom、Gemini 是 Google LLC 的商標;Claude 是 Anthropic PBC 的商標。
</sub>
</div>
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues