Community연구 & 데이터 분석github.com

DonAzufre/rain-class-reviewer

长江雨课堂 강의 슬라이드를 다운로드하고 구조화된 복습 자료를 CLI 및 설치 가능한 Agent Skill로 생성합니다.

rain-class-reviewer란 무엇인가요?

이 스킬은 **chrome-devtools-mcp**와 **로컬 Node.js 스크립트**를 결합하여 长江雨课堂(Changjiang Yuketang) 플랫폼에서 강의 자료를 자동으로 다운로드하고 복습 개요를 생성합니다. AI 에이전트(Claude Code, OpenCode, Cursor 등)가 브라우저 MCP를 통해 로그인 쿠키를 획득한 후, 모든 비즈니스 데이터 처리(강의 목록 조회, PPT 다운로드, Markdown 노트 추출, 복습 개요 생성)는 `scripts/bootstrap.js`라는 단일 CLI 스크립트로 위임됩니다. 이는 **MCP의 역할을 인증에만 제한**하여 보안과 안정성을 높입니다. 주요 기능으로는 날짜/강의 ID별 필터 다운로드, 각 PPT 페이지를 개별 Markdown 파일로 변환(제목, 핵심 개념, 공식 포함), 그리고 모든 페이지를 통합한 `review.md` 생성이 있습니다. MiMo API 키(`MIMO_TP_API_KEY`)를 사용하여 요약 기능을 제공하며, 쿠키와 API 키는 환경 변수로만 전달되어 민감 정보가 파일이나 대화 기록에 남지 않도록 설계되었습니다.

지원 대상✓Claude Code✓Codex CLI~Cursor✓OpenCode
npx skills add DonAzufre/rain-class-reviewer

Installed? Explore more 연구 & 데이터 분석 skills: affaan-m/uspto-database, affaan-m/scholar-evaluation, affaan-m/literature-review · View all 6 →

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

长江雨课堂 강의 슬라이드 다운로드 및 복습 개요 생성

중요: LLM 행동 경계

이 Skill은 브라우저 MCP와 로컬 스크립트의 책임을 엄격히 구분합니다. 다음 경계를 반드시 준수해야 하며, 경계를 넘는 작업은 금지됩니다.

chrome-devtools-mcp로 할 수 있는 일 (전용)

  1. https://changjiang.yuketang.cn/를 열고 로그인 상태를 확인합니다.
  2. 사용자가 로그인하지 않은 경우, 로그인을 완료하도록 안내하고 사용자 확인을 기다립니다.
  3. 로그인 후 쿠키 획득:
    • DevTools Network 요청 헤더를 통해 Cookie 필드를 우선적으로 읽습니다(HttpOnly 쿠키 포함 모든 쿠키 획득 가능).
    • 요청 헤더에서 획득할 수 없는 경우, 비 HttpOnly document.cookie를 읽는 것으로 대체할 수 있습니다.
  4. 스크립트가 처리할 수 없는 복잡/불명확한 작업(예: 페이지 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"}
  1. node <skill-path>/scripts/bootstrap.js verify-auth --manifest <skill-path>/tmp/manifest.json 로그인 상태 검증.
  2. node <skill-path>/scripts/bootstrap.js list-courses --manifest <skill-path>/tmp/manifest.json --json 강의 목록 획득.
  3. node <skill-path>/scripts/bootstrap.js --manifest <skill-path>/tmp/manifest.json --json 강의 슬라이드 다운로드 (기본 출력: 프로젝트 루트의 rain-class-reviewer-downloads/).
  4. 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 생성.

사전 조건

실행을 시작하기 전에 다음 명시적 검사를 순서대로 완료해야 합니다:

  1. Node.js 및 npm 확인

    • node -v 실행, 주 버전 >= 18 확인.
    • npm -v 실행, npm 사용 가능 확인.
    • 조건 미충족 시 중단하고 사용자에게 Node.js >= 18 설치 안내.
  2. chrome-devtools-mcp 확인

    • MCP 브라우저 도구를 한 번 호출해 봅니다(예: mcp__chrome-devtools__list_pages 또는 mcp__chrome-devtools__navigate_page).
    • MCP를 사용할 수 없으면 중단하고 사용자에게 Claude Code / OpenCode에서 chrome-devtools-mcp를 활성화했는지 확인하도록 안내.
  3. 요약에 필요한 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를 디스크에 쓰는 것을 금지.
  4. 사용자가 다운로드/요약할 강의명을 명시적으로 지정했는지 확인.

빠른 시작

모든 명령어는 현재 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/

작업 단계:

  1. 브라우저에 연결합니다.
  2. mcp__chrome-devtools__navigate_page를 사용하여 다음으로 이동:
    https://changjiang.yuketang.cn/
    
  3. 페이지가 이미 로드된 경우 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 읽기

  1. list_network_requests를 호출하여 최근 요청을 확인합니다.
  2. 요청 목록에서 다음 우선순위로 요청을 선택:
    • 우선: 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/* 요청
  3. get_network_request를 사용하여 해당 요청의 Request Headers를 읽습니다.
  4. 요청 헤더에서 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를 제공할 수 없는 경우:

  1. document.cookie를 읽어 비 HttpOnly Cookie를 획득해 봅니다(일반적으로 최소한 csrftoken은 얻을 수 있음).
  2. 여전히 sessionid를 얻을 수 없으면 사용자에게 수동으로 sessionid를 제공하도록 요청하거나 MCP가 HttpOnly Cookie 획득을 지원하는지 확인합니다.
  3. 대체 방안이 성공하든 실패하든, 최종적으로는 반드시 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 / 미로그인 / 인증 검증 실패를 반환하는 경우:

  1. sessionid가 만료되었거나 누락되었음을 설명합니다.
  2. 2단계(MCP를 사용한 확인/재로그인)를 다시 실행합니다.
  3. RAIN_COOKIES 환경 변수를 업데이트합니다.
  4. 스크립트를 다시 실행합니다.

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: 구현 세부 사항.

관련 스킬