長江雨課堂課件下載與複習大綱生成
重要:LLM 行為邊界
本 Skill 嚴格區分 瀏覽器 MCP 與 本地腳本 的職責。你必須遵守以下邊界,禁止越界操作。
你可以使用 chrome-devtools-mcp 做的事(僅限)
- 打開
https://changjiang.yuketang.cn/並檢查登入狀態。 - 在使用者未登入時,提示使用者完成登入,並等待使用者確認。
- 登入後獲取 Cookie:
- 優先透過 DevTools Network 請求頭讀取
Cookie欄位(可獲取包括 HttpOnly 在內的所有 Cookie)。 - 若請求頭中無法獲取,可回退到讀取非 HttpOnly 的
document.cookie。 - 處理腳本無法完成的複雜/模糊任務(如頁面人機驗證、需要使用者在頁面上手動點選的彈窗、瀏覽器獨有的登入流程)。
- 優先透過 DevTools Network 請求頭讀取
- 處理腳本無法完成的複雜/模糊任務(如頁面人機驗證、需要使用者在頁面上手動點選的彈窗、瀏覽器獨有的登入流程)。
禁止使用 chrome-devtools-mcp 做的事
- 呼叫課程列表、課時列表、PPT 提取等 API 並讀取回應資料來獲取業務資訊。
- 翻頁、抓圖、解析頁面 HTML 來獲取課程/課時/PPT 資料。
- 直接下載圖片。
- 直接生成或修改複習大綱。
- 用瀏覽器反覆探測介面正確性。
這些任務必須呼叫 scripts/bootstrap.js 實現。 具體介面清單見 references/yuketang-api.md。
關鍵區別:用 MCP 讀取網路請求的
Cookie請求頭屬於「獲取登入態」,是允許的;用 MCP 讀取 API 回應體屬於「獲取業務資料」,是禁止的。
最小 Manifest 構造後必須停止 MCP
一旦你透過 MCP 拿到 Cookie,立即停止所有 chrome-devtools-mcp 操作。Cookie 只能透過 RAIN_COOKIES 環境變數傳給腳本,Manifest 檔案只保留課程資訊。後續步驟必須交給腳本:
set RAIN_COOKIES={"sessionid":"...","csrftoken":"...","uv_id":"0","university_id":"0","xtbz":"ykt"}
node <skill-path>/scripts/bootstrap.js verify-auth --manifest <skill-path>/tmp/manifest.json校驗登入態。node <skill-path>/scripts/bootstrap.js list-courses --manifest <skill-path>/tmp/manifest.json --json獲取課程列表。node <skill-path>/scripts/bootstrap.js --manifest <skill-path>/tmp/manifest.json --json下載課件(預設輸出到專案根目錄的rain-class-reviewer-downloads/)。node <skill-path>/scripts/bootstrap.js summarize --course-dir "rain-class-reviewer-downloads/<課程名>" --force-summary提取筆記並生成複習大綱。
為相容 Claude Code auto mode 的安全策略,不要把 Manifest 透過 stdin 傳入,也不要在 Manifest 檔案中寫 Cookie。把最終 Manifest 寫入 Skill 目錄下的
tmp/manifest.json(覆蓋寫入),並在命令中透過路徑引用;Cookie 透過RAIN_COOKIES環境變數傳入。tmp/已在.gitignore中,不會進入版本控制。
只有在腳本明確報告需要人工處理(如驗證碼、需要使用者在瀏覽器裡點選)時,才允許再次啟用 MCP,且處理完後必須立刻回到腳本流程。
能力概述
- 自動登入態獲取:使用 chrome-devtools-mcp 連接瀏覽器,檢查/等待使用者登入後自動提取 Cookie(支援 HttpOnly Cookie)。
- 腳本化後續流程:登入態校驗、課程發現、課時列表、PPT 下載、Markdown 筆記提取、複習大綱生成全部透過本地腳本完成。
- 過濾下載:支援按日期、課時 ID、最新課時等條件下載。
- Markdown 筆記:每頁 PPT 儲存為獨立 Markdown 文件,包含標題、要點、公式、關鍵詞、核心概念和詳細總結。
- 複習大綱:跨頁面整合生成
review.md。
前置條件
開始執行前,必須依次完成以下顯式檢查:
-
檢查 Node.js 和 npm
- 執行
node -v,確認主版本號 >= 18。 - 執行
npm -v,確認 npm 可用。 - 任一不滿足時,停止並提示使用者安裝 Node.js >= 18。
- 執行
-
檢查 chrome-devtools-mcp
- 嘗試呼叫一次 MCP 瀏覽器工具(例如
mcp__chrome-devtools__list_pages或mcp__chrome-devtools__navigate_page)。 - 如果 MCP 不可用,停止並提示使用者確認 Claude Code / OpenCode 已啟用 chrome-devtools-mcp。
- 嘗試呼叫一次 MCP 瀏覽器工具(例如
-
檢查總結所需 API Key(僅在使用者要求生成複習大綱時)
- 檢查環境變數
MIMO_TP_API_KEY是否存在且以tp-開頭。 - 如果已存在,繼續執行。
- 如果不存在,向使用者詢問 MiMo API Key(以
tp-開頭)。 - 獲得使用者提供的 Key 後,在後續所有涉及總結的命令中透過環境變數傳入,例如:
set MIMO_TP_API_KEY=tp-xxxx node .claude/skills/rain-class-reviewer/scripts/bootstrap.js summarize --course-dir rain-class-reviewer-downloads/<課程名> - 禁止要求使用者把 Key 寫入檔案,也禁止 Skill 把 Key 寫入磁碟。
- 檢查環境變數
-
確認使用者已明確指定要下載/總結的課程名。
快速開始
所有命令應在當前 Claude Code / OpenCode 專案根目錄執行,透過 Skill 目錄的相對路徑呼叫腳本。scripts/bootstrap.js 會自動把專案根目錄當作工作目錄,因此:
- 相對路徑的
--manifest、-o、--course-dir、--lesson-dir等參數都以專案根目錄為基準解析,不會出現路徑重複。 - 不指定
--output時,預設下載目錄會生成在專案根目錄的rain-class-reviewer-downloads/下,而不是 Skill 安裝目錄下。
首次呼叫時 scripts/bootstrap.js 會優先使用預構建的 dist/cli.cjs(已包含 openai 等依賴),無需聯網安裝;若不存在才會自動 npm install。
完整流程
1. 詢問使用者課程名(或關鍵詞)。
2. 用 MCP 打開 https://changjiang.yuketang.cn/ 並獲取 Cookie(優先從 Network 請求頭讀取)。
3. 構造最小 Manifest JSON,寫入 <skill-path>/tmp/manifest.json。
4. 執行 node <skill-path>/scripts/bootstrap.js verify-auth --manifest <skill-path>/tmp/manifest.json 校驗登入態。
5. 執行 node <skill-path>/scripts/bootstrap.js list-courses --manifest <skill-path>/tmp/manifest.json --json 獲取課程列表。
6. 根據使用者輸入匹配課程;有歧義時向使用者展示候選並確認 classroomId。
7. 使用課程列表返回的原始 courseName,構造帶 classroomId 的 Manifest(覆蓋 tmp/manifest.json),執行 node <skill-path>/scripts/bootstrap.js --manifest <skill-path>/tmp/manifest.json --json 下載(預設輸出到 rain-class-reviewer-downloads/)。
8. 設定 `MIMO_TP_API_KEY` 後,執行 `node <skill-path>/scripts/bootstrap.js summarize --course-dir "rain-class-reviewer-downloads/<原始課程名>" --force-summary` 生成複習大綱。
範例(Claude Code 專案級 Skill 路徑為 .claude/skills/rain-class-reviewer):
node .claude/skills/rain-class-reviewer/scripts/bootstrap.js \
--manifest .claude/skills/rain-class-reviewer/tmp/manifest.json --json
標準執行流程
1. 獲取使用者期望的課程名
向使用者確認課程名,允許使用簡稱或關鍵詞,例如「計算機網路」。記錄使用者原始輸入,不要立即做任何匹配。
2. 使用 MCP 獲取 Cookie
長江雨課堂的 sessionid 通常是 HttpOnly Cookie,無法透過 document.cookie 讀取。你必須透過 Chrome DevTools Network 請求頭獲取,且必須嚴格使用下面列出的 URL。
2.1 打開長江雨課堂頁面
必須導航到的 URL:
https://changjiang.yuketang.cn/
操作步驟:
- 連接瀏覽器。
- 使用
mcp__chrome-devtools__navigate_page導航到:https://changjiang.yuketang.cn/ - 如果頁面已經載入過,使用
type=reload重新整理同一 URL,以產生新的網路請求:mcp__chrome-devtools__navigate_page: type=reload, url=https://changjiang.yuketang.cn/
2.2 觸發一條帶 Cookie 的網路請求
重新整理頁面後,瀏覽器通常會自動產生多個帶 Cookie 的請求。如果沒有出現足夠的請求,必須主動觸發下列 URL:
首選觸發 URL(該 URL 與腳本後續 verify-auth / list-courses 使用的課程列表介面完全一致,安全且可重複使用):
GET https://changjiang.yuketang.cn/v2/api/web/courses/list?identity=2
觸發方式(任選其一,僅用於產生請求流量,禁止讀取回應業務資料):
- 方式 A:執行一次頁面重新整理(見 2.1)。
- 方式 B:透過
evaluate_script執行:fetch('https://changjiang.yuketang.cn/v2/api/web/courses/list?identity=2', { credentials: 'include' });
備用觸發 URL(當首選請求未出現時,任何發往 changjiang.yuketang.cn 的請求均可):
https://changjiang.yuketang.cn/ (頁面文件)
https://changjiang.yuketang.cn/v2/web/index (首頁入口)
https://changjiang.yuketang.cn/* (同域名下的靜態資源,如 JS/CSS)
禁止使用其他雨課堂子域名或第三方介面來探測 Cookie。
2.3 從 Network 請求頭中讀取 Cookie
- 呼叫
list_network_requests查看最近的請求。 - 在請求列表中按以下優先級選擇一條請求:
- 優先:
https://changjiang.yuketang.cn/v2/api/web/courses/list?identity=2 - 次選:
https://changjiang.yuketang.cn/或https://changjiang.yuketang.cn/v2/web/index - 可接受:任何
https://changjiang.yuketang.cn/*請求
- 優先:
- 使用
get_network_request讀取該請求的 Request Headers。 - 在請求頭中找到
cookie或Cookie欄位,解析以下欄位:sessionid(必須)csrftoken(建議攜帶,用於 CSRF 校驗)uv_id(按實際值提取,可能是0或其他值)university_id(按實際值提取,可能與uv_id相同或不同)xtbz(通常為ykt)django_language(可選)
範例 Cookie 頭:
sessionid=abc123; csrftoken=xyz789; uv_id=0; university_id=0; xtbz=ykt
不要硬編碼
uv_id=2874或university_id=2874,必須從請求頭中讀取實際值。缺失或0都是允許的。
2.4 處理未登入情況
- 如果請求頭中沒有
sessionid,或請求被重新導向到登入頁,說明使用者未登入。 - 提示使用者手動登入長江雨課堂。
- 等待使用者回覆「已登入」。
- 重新整理頁面或再次觸發
https://changjiang.yuketang.cn/v2/api/web/courses/list?identity=2,重新讀取 Cookie。
2.5 回退方案
如果 MCP 無法提供請求頭中的 Cookie:
- 嘗試讀取
document.cookie獲取非 HttpOnly Cookie(通常至少能拿到csrftoken)。 - 如果仍無法拿到
sessionid,請使用者手動提供sessionid,或檢查 MCP 是否支援獲取 HttpOnly Cookie。 - 無論回退是否成功,最終仍然必須透過 Network 請求頭拿到
sessionid。
3. 構造最小 Manifest
{
"version": "1.0",
"courseName": "計算機網路"
}
courseName 使用使用者原始輸入。此 Manifest 只用於校驗和獲取課程列表,不保證最終匹配。構造完此 Manifest 後,立即停止 MCP。
Cookie 透過 RAIN_COOKIES 環境變數傳入(下同):
set RAIN_COOKIES={"sessionid":"...","csrftoken":"...","uv_id":"0","university_id":"0","xtbz":"ykt"}
4. 校驗登入態
set RAIN_COOKIES={...}
node <skill-path>/scripts/bootstrap.js verify-auth --manifest <skill-path>/tmp/manifest.json
- 成功:繼續下一步。
- 失敗:返回步驟 2,重新獲取 Cookie。
5. 獲取課程列表
set RAIN_COOKIES={...}
node <skill-path>/scripts/bootstrap.js list-courses --manifest <skill-path>/tmp/manifest.json --json
返回目前帳號下所有課程的 classroomId、courseName、className、teacher。
6. 匹配課程並處理歧義
用使用者原始輸入匹配課程列表:
- 唯一精確匹配:直接使用該
classroomId。 - 無匹配:向使用者展示所有可用課程,要求使用者指定課程名或
classroomId。 - 多個匹配:向使用者展示候選課程(含班級、教師、classroomId),要求使用者確認。
禁止擅自選擇。 確認後,使用課程列表返回的原始 courseName 構造新的 Manifest,並覆蓋寫入 tmp/manifest.json:
{
"version": "1.0",
"courseName": "計算機網路",
"classroomId": "13522533"
}
7. 下載課件
set RAIN_COOKIES={...}
node <skill-path>/scripts/bootstrap.js --manifest <skill-path>/tmp/manifest.json --json
8. 提取 Markdown 筆記並生成複習大綱
set MIMO_TP_API_KEY=tp-xxxx
node <skill-path>/scripts/bootstrap.js summarize --course-dir "rain-class-reviewer-downloads/<課程名>" --force-summary
輸出:
- 每頁 Markdown 筆記:
rain-class-reviewer-downloads/<課程名>/extracted/<課時>/<頁碼>.md - 整體複習大綱:
rain-class-reviewer-downloads/<課程名>/review.md
按課時過濾下載
只下載最新一次課時:
node <skill-path>/scripts/bootstrap.js --manifest <skill-path>/tmp/manifest.json --latest --json
按日期範圍下載:
node <skill-path>/scripts/bootstrap.js --manifest <skill-path>/tmp/manifest.json --since 2023-11-01 --until 2023-11-05 --json
課程名歧義處理
- 若存在多個同名課程,腳本會報錯並列出候選
classroomId。 - 禁止擅自選擇,必須向使用者展示候選課程並要求確認。
- 確認後,在 Manifest 中顯式指定
classroomId再呼叫腳本。
認證失敗處理
若腳本返回 403 / 未登入 / 認證校驗失敗:
- 說明
sessionid已過期或缺失。 - 重新執行步驟 2(使用 MCP 檢查/重新登入)。
- 更新
RAIN_COOKIES環境變數。 - 重新執行腳本。
Claude Code 自動模式特別說明
本 Skill 的 Manifest 檔案不再包含 Cookie 等憑證;Cookie 只能透過 RAIN_COOKIES 環境變數傳遞。因此 Write(tmp/manifest.json) 只寫入課程名/classroomId,通常可以通過 auto mode 的檔案寫入檢查。
如果 auto mode 仍然攔截寫入臨時檔案,可在當前專案根目錄手動建立 .claude/policy.json:
{
"autoMode": {
"allow": [
"Allow writing the rain-class-reviewer skill manifest file at .claude/skills/rain-class-reviewer/tmp/manifest.json, which only contains course name and classroomId.",
"Allow running node .claude/skills/rain-class-reviewer/scripts/bootstrap.js commands for course download and summarization."
]
}
}
所有命令都應附帶 RAIN_COOKIES 環境變數:
set RAIN_COOKIES={"sessionid":"...","csrftoken":"...","uv_id":"0","university_id":"0","xtbz":"ykt"}
node .claude/skills/rain-class-reviewer/scripts/bootstrap.js verify-auth --manifest .claude/skills/rain-class-reviewer/tmp/manifest.json
Git Bash / Linux / macOS 使用
export RAIN_COOKIES='...'。
安全與隱私
- 禁止在對話中明文輸出完整 Cookie。
- Manifest 寫入 Skill 目錄下的
tmp/manifest.json,覆蓋之前的內容;Manifest 中不得包含 cookies 欄位。tmp/已在.gitignore中,不會進入版本控制。 - Cookie 只能透過
RAIN_COOKIES環境變數傳遞,不要單獨儲存cookies.json。 - 下載目錄
rain-class-reviewer-downloads/和暫存目錄tmp/已在.gitignore中。
已知限制
- 工具優先使用新版
lesson-summary+presentation介面獲取完整 PPT;若不可用會自動回退到review介面,但後者只包含課堂中展示過的幻燈片。 - 總結功能依賴 MiMo API Key,必須透過
MIMO_TP_API_KEY環境變數傳入;禁止寫入檔案。
參考
references/yuketang-api.md:長江雨課堂介面清單與約束。references/manifest.example.json:Manifest 完整範例。docs/usage.md:CLI 完整參數說明。docs/implementation.md:實作細節。