长江雨课堂 강의 슬라이드 다운로드 및 복습 개요 생성
중요: LLM 행동 경계
이 Skill은 브라우저 MCP와 로컬 스크립트의 책임을 엄격히 구분합니다. 다음 경계를 반드시 준수해야 하며, 경계를 넘는 작업은 금지됩니다.
chrome-devtools-mcp로 할 수 있는 일 (전용)
https://changjiang.yuketang.cn/를 열고 로그인 상태를 확인합니다.- 사용자가 로그인하지 않은 경우, 로그인을 완료하도록 안내하고 사용자 확인을 기다립니다.
- 로그인 후 쿠키 획득:
- DevTools Network 요청 헤더를 통해
Cookie필드를 우선적으로 읽습니다(HttpOnly 쿠키 포함 모든 쿠키 획득 가능). - 요청 헤더에서 획득할 수 없는 경우, 비 HttpOnly
document.cookie를 읽는 것으로 대체할 수 있습니다.
- DevTools Network 요청 헤더를 통해
- 스크립트가 처리할 수 없는 복잡/불명확한 작업(예: 페이지 CAPTCHA, 사용자가 페이지에서 수동으로 클릭해야 하는 팝업, 브라우저 고유의 로그인流程)을 처리합니다.
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 자동 모드의 보안 정책 호환성을 위해 Manifest를 stdin으로 전달하지 말고, Manifest 파일에 Cookie를 작성하지 마세요. 최종 Manifest를 Skill 디렉토리 아래
tmp/manifest.json에 작성(덮어쓰기)하고, 명령어에서 경로로 참조하세요. Cookie는RAIN_COOKIES환경 변수로 전달합니다.tmp/는.gitignore에 포함되어 버전 관리에 들어가지 않습니다.
스크립트가 명시적으로 수동 처리가 필요하다고 보고하는 경우(예: CAPTCHA, 사용자가 브라우저에서 클릭해야 하는 경우)에만 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을 지정하지 않으면 기본 다운로드 디렉토리는 Skill 설치 디렉토리가 아닌 프로젝트 루트의rain-class-reviewer-downloads/아래에 생성됩니다.
첫 호출 시 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: 구현 세부 사항.