cau-eclass-mcp 0.2.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.
Files changed (31) hide show
  1. cau_eclass_mcp-0.2.0/.gitignore +32 -0
  2. cau_eclass_mcp-0.2.0/CHANGELOG.md +16 -0
  3. cau_eclass_mcp-0.2.0/CONTRIBUTING.md +17 -0
  4. cau_eclass_mcp-0.2.0/LICENSE +58 -0
  5. cau_eclass_mcp-0.2.0/NOTICE +10 -0
  6. cau_eclass_mcp-0.2.0/PKG-INFO +272 -0
  7. cau_eclass_mcp-0.2.0/README.md +246 -0
  8. cau_eclass_mcp-0.2.0/SECURITY.md +11 -0
  9. cau_eclass_mcp-0.2.0/docs/architecture.md +35 -0
  10. cau_eclass_mcp-0.2.0/docs/cdp.md +60 -0
  11. cau_eclass_mcp-0.2.0/docs/distribution.md +57 -0
  12. cau_eclass_mcp-0.2.0/examples/claude-cdp.json +13 -0
  13. cau_eclass_mcp-0.2.0/examples/codex-cdp.toml +8 -0
  14. cau_eclass_mcp-0.2.0/examples/vscode-cdp.json +14 -0
  15. cau_eclass_mcp-0.2.0/mcp.example.json +11 -0
  16. cau_eclass_mcp-0.2.0/pyproject.toml +58 -0
  17. cau_eclass_mcp-0.2.0/scripts/check_dist.py +37 -0
  18. cau_eclass_mcp-0.2.0/scripts/check_install.py +63 -0
  19. cau_eclass_mcp-0.2.0/skills/cau-eclass/SKILL.md +24 -0
  20. cau_eclass_mcp-0.2.0/src/eclass_mcp/__init__.py +1 -0
  21. cau_eclass_mcp-0.2.0/src/eclass_mcp/browser_scripts.py +60 -0
  22. cau_eclass_mcp-0.2.0/src/eclass_mcp/cdp.py +277 -0
  23. cau_eclass_mcp-0.2.0/src/eclass_mcp/cli.py +126 -0
  24. cau_eclass_mcp-0.2.0/src/eclass_mcp/config.py +16 -0
  25. cau_eclass_mcp-0.2.0/src/eclass_mcp/server.py +173 -0
  26. cau_eclass_mcp-0.2.0/src/eclass_mcp/service.py +502 -0
  27. cau_eclass_mcp-0.2.0/src/eclass_mcp/transport.py +274 -0
  28. cau_eclass_mcp-0.2.0/tests/test_cdp_browser.py +162 -0
  29. cau_eclass_mcp-0.2.0/tests/test_distribution.py +119 -0
  30. cau_eclass_mcp-0.2.0/tests/test_server.py +243 -0
  31. cau_eclass_mcp-0.2.0/uv.lock +1628 -0
@@ -0,0 +1,32 @@
1
+ # Browser sessions and downloaded course material are local-only.
2
+ .env
3
+ .env.*
4
+ !.env.example
5
+ .session/
6
+ downloads/
7
+ *.har
8
+ *.cookies
9
+ storage-state*.json
10
+ .venv/
11
+ __pycache__/
12
+ .pytest_cache/
13
+ .ruff_cache/
14
+ test-results/
15
+ *.egg-info/
16
+
17
+ # Machine-specific MCP configuration; commit the example instead.
18
+ /mcp.json
19
+ /.DS_Store
20
+ /build/
21
+ /dist/
22
+
23
+ # Downloaded third-party bundles and local reverse-engineering evidence.
24
+ /analysis/public/
25
+ /analysis/learningx-public/
26
+ /analysis/public-rea-summary.json
27
+
28
+ # Local authentication artifacts.
29
+ /.credentials/
30
+ /.secrets/
31
+ *.pem
32
+ *.key
@@ -0,0 +1,16 @@
1
+ # Changelog
2
+
3
+ ## 0.2.0 — 배포 준비
4
+
5
+ - Aside 및 로컬 Chromium CDP 어댑터 선택.
6
+ - 브라우저 API 스크립트 공유, CDP 연결 해제 시 사용자 브라우저 유지.
7
+ - `serve`, `doctor`, `config`, `skill`, `--version` CLI.
8
+ - Claude/Cursor, VS Code, Codex 설정 출력과 에이전트 스킬 포함.
9
+ - OZ 계획서 PDF·본문 추출, 원본 영상 요청과 명시적 재생용 MP4 대체 옵션.
10
+ - 기본 다운로드 위치: `~/Downloads/cau-eclass` (`ECLASS_DOWNLOAD_DIR`로 변경 가능).
11
+ - wheel/sdist 빌드, 민감한 로컬 산출물 제외, CI와 synthetic CDP 테스트.
12
+ - 실제 제출은 기본 비활성화. PyPI/Registry 공개 게시 전 단계.
13
+
14
+ ## 0.1.0
15
+
16
+ - Aside 기반 Canvas/LearningX 조회·Canvas 첨부 다운로드·과제 제출 준비.
@@ -0,0 +1,17 @@
1
+ # 개발
2
+
3
+ Python 3.12 이상과 uv를 사용합니다.
4
+
5
+ ```sh
6
+ uv sync --frozen --extra cdp
7
+ uv run pytest -q
8
+ uv run ruff check src tests scripts
9
+ uv build --no-sources
10
+ uv run python scripts/check_dist.py
11
+ ```
12
+
13
+ 실제 CDP 테스트는 `ECLASS_TEST_CHROME`에 Chrome/Chromium 실행 파일 경로를 설정하고 `uv run pytest tests/test_cdp_browser.py -q`로 실행합니다. 테스트는 임시 프로필과 synthetic 사이트 응답을 사용하며 작업이 만든 브라우저만 종료합니다. 실제 계정 테스트는 본인에게 허용된 자료로 실행하고, 과제 제출·업로드·영상 재생·진도 갱신은 검증 명목으로 실행하지 마세요.
14
+
15
+ `browser_scripts.py`는 두 어댑터가 공유하는 페이지 내 요청 코드입니다. 서비스의 데이터 해석/제출 계획과 브라우저 연결/파일 전송 로직을 분리하세요. 인증값·서명 URL을 예외, fixture, 로그, PR에 넣지 마세요. 테스트 데이터는 가상 계정·가상 ID를 사용합니다. MCP stdout은 프로토콜 전용입니다.
16
+
17
+ 배포 산출물 검증은 [배포 문서](docs/distribution.md)를 따릅니다. `scripts/live_*.py`는 이전 실계정 조사 도구이며 일반 CI에서 실행하지 않습니다.
@@ -0,0 +1,58 @@
1
+ CAU e-Class Noncommercial License 1.0
2
+ SPDX-License-Identifier: LicenseRef-CAU-EClass-Noncommercial-1.0
3
+
4
+ Copyright (c) 2026 givemethatsewon
5
+
6
+ 1. Scope
7
+
8
+ This license applies to the original software, documentation, and agent skills
9
+ in this project (the "Software"). It does not replace the licenses of separate
10
+ third-party dependencies or grant rights in university content, course materials,
11
+ trademarks, accounts, or data accessed using the Software.
12
+
13
+ 2. Noncommercial permission
14
+
15
+ Subject to these terms, you may use, copy, study, modify, and redistribute the
16
+ Software, including modified versions, solely for noncommercial purposes.
17
+ Noncommercial purposes include personal study, private experimentation, and
18
+ research that is not directed toward commercial advantage or monetary gain.
19
+
20
+ 3. Commercial use is prohibited
21
+
22
+ You may not use, modify, distribute, or otherwise exploit the Software for
23
+ commercial advantage, monetary compensation, or the operation of a business.
24
+ Prohibited uses include selling or charging for the Software or access to it;
25
+ including it in a paid, subscription, advertising-supported, or otherwise
26
+ revenue-generating product or service; providing paid hosting, consulting, or
27
+ other services using it; and using it for internal business operations or on
28
+ behalf of commercial customers.
29
+
30
+ This restriction applies to all persons and organizations, including educational,
31
+ nonprofit, charitable, and government organizations when their use is commercial.
32
+ An organization's legal status or source of funding does not create an exception.
33
+ No commercial-use exception or commercial license is granted by these terms.
34
+
35
+ 4. Redistribution and modifications
36
+
37
+ Every copy or substantial portion of the Software you redistribute must include
38
+ this license and the copyright notice. Identify your modifications and their
39
+ author. Redistribute the original Software and modifications to it only under
40
+ these same terms; do not remove, weaken, or override the commercial-use
41
+ restriction. Recipients receive permission directly under this license, not
42
+ under a broader sublicense from you. You may not charge a fee for redistribution.
43
+
44
+ 5. Reserved rights and termination
45
+
46
+ All rights not expressly granted are reserved. No trademark rights or rights
47
+ to impersonate the author or Chung-Ang University are granted. Your permission
48
+ under this license terminates automatically if you violate its terms. These
49
+ terms do not restrict rights that cannot lawfully be restricted, including
50
+ applicable statutory exceptions.
51
+
52
+ 6. No warranty or liability
53
+
54
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
55
+ IMPLIED, INCLUDING WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
56
+ PURPOSE, AND NON-INFRINGEMENT. TO THE EXTENT PERMITTED BY LAW, THE COPYRIGHT
57
+ HOLDER SHALL NOT BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY ARISING
58
+ FROM THE SOFTWARE OR ITS USE.
@@ -0,0 +1,10 @@
1
+ CAU e-Class MCP
2
+ Copyright (c) 2026 givemethatsewon
3
+
4
+ Source-available for noncommercial use only. Commercial use is prohibited.
5
+ License: LicenseRef-CAU-EClass-Noncommercial-1.0 (see LICENSE).
6
+ This is a project-specific license, not MIT, PolyForm, or an OSI-approved license.
7
+
8
+ This is an unofficial project, not affiliated with or endorsed by Chung-Ang
9
+ University. The project license covers its original code, documentation and
10
+ skills, not third-party dependencies or university/course materials.
@@ -0,0 +1,272 @@
1
+ Metadata-Version: 2.5
2
+ Name: cau-eclass-mcp
3
+ Version: 0.2.0
4
+ Summary: CAU e-Class MCP for authenticated Aside or Chromium CDP sessions
5
+ Project-URL: Repository, https://github.com/givemethatsewon/cau-eclass-mcp
6
+ Project-URL: Issues, https://github.com/givemethatsewon/cau-eclass-mcp/issues
7
+ Project-URL: Documentation, https://github.com/givemethatsewon/cau-eclass-mcp#readme
8
+ Author: givemethatsewon
9
+ License-Expression: LicenseRef-CAU-EClass-Noncommercial-1.0
10
+ License-File: LICENSE
11
+ License-File: NOTICE
12
+ Keywords: canvas,cau,chromium,learningx,mcp
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Topic :: Education
17
+ Requires-Python: >=3.12
18
+ Requires-Dist: beautifulsoup4<5,>=4.12
19
+ Requires-Dist: fastmcp==4.1.4
20
+ Requires-Dist: httpx<1,>=0.28
21
+ Requires-Dist: pypdf<7,>=6
22
+ Requires-Dist: tzdata>=2025.2
23
+ Provides-Extra: cdp
24
+ Requires-Dist: playwright<2,>=1.60; extra == 'cdp'
25
+ Description-Content-Type: text/markdown
26
+
27
+ # CAU e-Class MCP
28
+
29
+ **비공식 중앙대학교 e-Class 도구 · 비상업적 사용만 허용 · 상업적 사용 금지**
30
+
31
+ 중앙대학교 e-Class의 강좌·공지·과제·마감일을 조회하고, 자료·계획서 PDF·영상을 내려받는 로컬 MCP 서버입니다. FastMCP 4.1.4를 사용하며 MCP 클라이언트와 stdio로 통신합니다.
32
+
33
+ ## 설치
34
+
35
+ Python 3.12 이상과 [uv](https://docs.astral.sh/uv/getting-started/installation/)가 필요합니다. **0.2.0 초기 배포판**입니다.
36
+
37
+ ### PyPI로 설치
38
+
39
+ ```sh
40
+ # Chrome·Edge 등 로컬 Chromium CDP 사용
41
+ uv tool install --python 3.12 'cau-eclass-mcp[cdp]==0.2.0'
42
+
43
+ # 설치 확인
44
+ eclass-mcp --version
45
+ ```
46
+
47
+ Aside만 사용한다면 `uv tool install --python 3.12 cau-eclass-mcp==0.2.0`으로 설치합니다.
48
+ [PyPI](https://pypi.org/project/cau-eclass-mcp/) · [GitHub Releases](https://github.com/givemethatsewon/cau-eclass-mcp/releases)
49
+
50
+ ### 전달받은 wheel로 설치
51
+
52
+ 저장소 checkout 없이 wheel 파일을 설치할 수 있습니다. 아래 경로는 전달받은 파일 위치로 바꿉니다.
53
+
54
+ ```sh
55
+ # Chrome·Edge 등 로컬 Chromium CDP 사용
56
+ uv tool install --python 3.12 --from /absolute/path/cau_eclass_mcp-0.2.0-py3-none-any.whl --with 'playwright>=1.60,<2' cau-eclass-mcp
57
+
58
+ # 설치 확인
59
+ uv tool run eclass-mcp --version
60
+ ```
61
+
62
+ Aside만 사용하는 경우 설치 명령의 `--with 'playwright>=1.60,<2'`를 생략합니다. `eclass-mcp`가 PATH에 없다면 아래 명령에서도 `uv tool run eclass-mcp`를 사용하거나 `uv tool update-shell` 후 터미널을 다시 엽니다.
63
+
64
+ ### 소스에서 실행
65
+
66
+ ```sh
67
+ uv sync --frozen --extra cdp
68
+ uv run eclass-mcp --help
69
+ ```
70
+
71
+ 이하의 `eclass-mcp` 명령은 소스 실행 시 `uv run eclass-mcp`로 바꾸면 됩니다. 설치된 Chrome·Edge에 연결만 하므로 `playwright install`로 별도 브라우저를 받을 필요는 없습니다.
72
+
73
+ ## 브라우저 선택과 로그인
74
+
75
+ | 방식 | 필요한 것 | 선택 |
76
+ |---|---|---|
77
+ | Chromium CDP | 전용 프로필로 remote debugging을 켠 Chrome·Edge 등 | `--browser cdp` |
78
+ | Aside | 실행 중인 로컬 Aside, `aside` CLI | `--browser aside` (기본값) |
79
+
80
+ ### Chromium CDP
81
+
82
+ [운영체제별 CDP 시작 가이드](docs/cdp.md)에 따라 브라우저를 실행합니다. macOS Chrome 예시:
83
+
84
+ ```sh
85
+ "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \
86
+ --remote-debugging-address=127.0.0.1 \
87
+ --remote-debugging-port=9222 \
88
+ --user-data-dir="$HOME/.cau-eclass/chrome-profile" \
89
+ https://eclass3.cau.ac.kr/
90
+ ```
91
+
92
+ 이 전용 프로필에서 직접 로그인하고 **주차학습 (모듈)** 화면을 한 번 연 뒤 탭을 유지합니다. 최초 로그인 이후에는 같은 프로필을 재사용합니다. 평소 프로필의 쿠키를 복사하지 않습니다.
93
+
94
+ ```sh
95
+ eclass-mcp --browser cdp --cdp-endpoint http://127.0.0.1:9222 doctor
96
+ ```
97
+
98
+ ### Aside
99
+
100
+ Aside에서 https://eclass3.cau.ac.kr/ 에 로그인하고 **주차학습 (모듈)** 화면을 한 번 엽니다. 탭과 Aside를 유지합니다.
101
+
102
+ ```sh
103
+ aside --help
104
+ eclass-mcp --browser aside doctor
105
+ ```
106
+
107
+ `doctor`는 프로필 조회로 연결·로그인을 검사하고 `ok: true/false`를 출력합니다. 이름·학번·쿠키는 출력하지 않습니다. 실패 시 종료 코드는 1입니다. 로그인 만료 시 선택한 브라우저에서 다시 로그인하세요.
108
+
109
+ ## MCP 클라이언트 연결
110
+
111
+ 설치 진단이 통과한 브라우저 설정으로 클라이언트 설정을 생성합니다. 이 명령은 설정을 **출력만** 하며 파일을 덮어쓰거나 클라이언트를 변경하지 않습니다.
112
+
113
+ ```sh
114
+ # Claude Desktop 또는 Cursor 형식
115
+ eclass-mcp --browser cdp --cdp-endpoint http://127.0.0.1:9222 config --client claude
116
+
117
+ # VS Code 형식
118
+ eclass-mcp --browser cdp config --client vscode
119
+
120
+ # Codex TOML 형식
121
+ eclass-mcp --browser cdp config --client codex
122
+ ```
123
+
124
+ Aside는 `--browser aside`로 바꾸고 CDP 옵션을 생략합니다. 필요하면 `--download-dir /absolute/path/downloads`도 함께 전달하세요. 공통 옵션은 `doctor`, `config`, `serve` 등의 명령 **앞에** 놓습니다.
125
+
126
+ 출력을 사용하는 클라이언트의 MCP 설정에 병합한 뒤 연결을 다시 시작합니다. 설정의 Python 경로는 설치 환경의 절대 경로이므로 패키지 설치 위치를 바꾸면 다시 생성하세요. `config`는 실제 제출을 항상 비활성화한 설정을 출력합니다. 형식별 예시는 [examples/](examples/)에 있습니다.
127
+
128
+ 서버만 직접 실행하려면:
129
+
130
+ ```sh
131
+ eclass-mcp --browser cdp serve
132
+ ```
133
+
134
+ 기본 명령도 `serve`입니다. 웹 포트를 제공하지 않고 stdio로 MCP 요청을 기다립니다. 사용자 브라우저는 서버 종료 후에도 유지됩니다.
135
+
136
+ ## 에이전트 스킬 설치 (선택)
137
+
138
+ 스킬은 과목 ID 선택, 마감일 해석, 원본/재생용 영상 구분, 제출 경계를 에이전트에 안내합니다. MCP 설치·브라우저 로그인을 대신하지 않습니다.
139
+
140
+ ```sh
141
+ mkdir -p ~/.agents/skills/cau-eclass
142
+ eclass-mcp skill > ~/.agents/skills/cau-eclass/SKILL.md
143
+ ```
144
+
145
+ 이미 같은 스킬이 있다면 덮어쓰기 전에 내용을 확인하세요. 클라이언트가 다른 스킬 디렉터리를 사용하면 경로를 바꿉니다. 저장소의 [SKILL.md](skills/cau-eclass/SKILL.md)를 직접 설치할 수도 있습니다.
146
+
147
+ ## 연결 확인과 사용
148
+
149
+ 연결한 에이전트에게 다음 순서로 요청합니다.
150
+
151
+ > eclass의 로그인 상태를 확인하고, 내 강좌 목록을 보여줘.
152
+
153
+ `get_session_status`와 `list_courses`로 확인할 수 있습니다. 현재 제공하는 도구는 **21개**입니다. 과목 ID는 강좌 목록에서, 과제·파일·영상 ID는 해당 목록이나 상세 응답에서 선택합니다.
154
+
155
+ 사용 예시:
156
+
157
+ - “컴퓨터그래픽스 공지를 이번 학기 시작일부터 오늘까지 조회해줘.”
158
+ - “빅데이터 과제와 마감일을 한국 시간으로 정리해줘.”
159
+ - “이 과목의 강의계획서를 PDF로 저장하고 본문을 읽어줘.”
160
+ - “이 첨부파일을 다운로드해줘.”
161
+ - “이 영상 원본을 다운로드해줘. 원본 서버가 실패하면 재생용 MP4로 받아도 돼.”
162
+ - “이 파일을 과제로 제출할 수 있는지 준비 검사만 해줘. 제출하지 마.”
163
+
164
+ 직접 도구를 호출하는 클라이언트에서는 다음 인자를 사용합니다. 숫자는 형식 예시이며 본인 계정의 ID로 바꿔야 합니다.
165
+
166
+ | 도구 | 인자 예시 |
167
+ |---|---|
168
+ | `list_announcements` | `{"course_id":123,"start_date":"2026-09-01","end_date":"2026-12-31"}` |
169
+ | `list_deadlines` | `{"course_id":123}` |
170
+ | `download_attachment` | `{"course_id":123,"file_id":456}` |
171
+ | `download_syllabus_pdf` | `{"course_id":123,"extract_text":true}` |
172
+ | `download_video_original` | `{"course_id":123,"item_id":789,"allow_playback_copy":false}` |
173
+ | `prepare_submission` | `{"course_id":123,"assignment_id":456,"files":["/absolute/path/work.pdf"]}` |
174
+
175
+ 도구 응답은 `observed_at`과 `result`로 구성됩니다. 목록의 `complete`·페이지 정보를 확인해 누락된 페이지가 없는지 판단하세요.
176
+
177
+ ## 다운로드
178
+
179
+ 기본 저장 위치는 사용자 홈의 `~/Downloads/cau-eclass/`입니다. `ECLASS_DOWNLOAD_DIR` 또는 `--download-dir`로 바꿀 수 있습니다. 결과에 로컬 절대 경로, 파일 크기, SHA-256이 반환되며 기존 파일을 덮어쓰지 않습니다.
180
+
181
+ | 대상 | 사용 방법과 제한 |
182
+ |---|---|
183
+ | Canvas 첨부 | `download_attachment`: Canvas file ID 사용, 최대 64 MiB. OCS 일반 주차자료와 LearningX 게시판 전용 첨부는 미지원 |
184
+ | 계획서 | `download_syllabus_pdf`: OZ의 Save → Adobe PDF로 전체 페이지 저장. `extract_text=true`가 기본값이며 페이지별 본문도 반환. `false`는 PDF만 저장. 64 MiB 초과 결과는 거부 |
185
+ | 영상 | `download_video_original`: 접근 가능한 Commons MP4 대상, 최대 1 GiB. `not_open` 영상은 거부 |
186
+
187
+ 계획서는 브라우저 인쇄본이 아닌 **OZ 네이티브 PDF 내보내기**입니다. OCR은 하지 않으며, 텍스트가 추출되지 않은 페이지가 있으면 `text_complete=false`를 반환합니다. `get_syllabus`는 별도로 HTML 본문과 뷰어 링크를 조회하는 도구입니다.
188
+
189
+ 실제 시험한 영상 원본 다운로드 주소는 학교 서버에서 HTTP 500을 반환했습니다. 기본 설정에서는 오류를 반환합니다. `allow_playback_copy=true`를 명시하면 플레이어의 정적 메타데이터에 제공된 MP4를 대신 내려받습니다. 이 경우 **`source=commons_playback_mp4`, `original=false`**로 반환합니다. 원본 다운로드 성공 시에는 `source=commons_original`, `original=true`입니다.
190
+
191
+ 영상 다운로드 과정에서 플레이어 스크립트·재생·진도 API를 실행하지 않습니다. 다운로드는 출석이나 학습 완료로 인정되지 않습니다.
192
+
193
+ ## 전체 도구
194
+
195
+ | 기능 | 도구 |
196
+ |---|---|
197
+ | 세션·강좌 | `get_session_status`, `list_courses` |
198
+ | 주차학습 | `list_learning_items` |
199
+ | 공지 | `list_announcements`, `get_announcement` |
200
+ | 과제·마감 | `list_assignments`, `get_assignment`, `list_deadlines`, `get_submission` |
201
+ | 계획서 | `get_syllabus`, `download_syllabus_pdf` |
202
+ | 게시판 | `list_boards`, `list_board_posts`, `get_board_post` |
203
+ | 그룹 | `list_my_groups`, `get_group_activity` |
204
+ | 다운로드 | `download_attachment`, `get_video_download_info`, `download_video_original` |
205
+ | 제출 준비·제출 | `prepare_submission`, `submit_assignment` |
206
+
207
+ ## 설정
208
+
209
+ | 환경 변수 | 기본값 | 용도 |
210
+ |---|---|---|
211
+ | `ECLASS_BROWSER` | `aside` | `aside` 또는 `cdp` 선택 |
212
+ | `ECLASS_CDP_ENDPOINT` | `http://127.0.0.1:9222` | 로컬 Chromium CDP 주소 |
213
+ | `ECLASS_ASIDE_BIN` | `aside` | Aside CLI 경로 |
214
+ | `ECLASS_ASIDE_PROFILE` | Aside 기본 프로필 | 로그인된 Aside 프로필 선택 |
215
+ | `ECLASS_DOWNLOAD_DIR` | `~/Downloads/cau-eclass` | 다운로드 폴더. 절대 경로 권장 |
216
+ | `ECLASS_ENABLE_SUBMISSION` | 비활성화 | 정확히 `1`일 때만 실험적 실제 제출 허용 |
217
+
218
+ 환경 변수는 MCP 클라이언트가 서버를 시작할 때 전달해야 합니다. 변경 후에는 연결을 다시 시작하세요. `.env` 파일을 자동으로 읽는 기능은 없습니다. 개인용 `mcp.json`, 다운로드, 세션·인증 파일은 Git에서 제외합니다.
219
+
220
+ ### 과제 제출
221
+
222
+ **실제 업로드·제출은 운영 검증되지 않은 실험 기능**입니다. 기본 설정 `ECLASS_ENABLE_SUBMISSION=0`을 유지하세요.
223
+
224
+ `prepare_submission`은 파일 해시·확장자·과제 잠금·기존 제출을 검사하고 유효기간 10분의 로컬 계획을 만듭니다. 파일을 업로드하지 않습니다. 실제 제출을 명시적으로 요청한 경우에만 설정을 `1`로 바꾸고, 준비 결과의 plan ID와 `SUBMIT <assignment_id>` 확인 문자열로 `submit_assignment`를 호출합니다.
225
+
226
+ Canvas 일반 파일 과제만 대상으로 하며 그룹·외부 originality 과제는 차단합니다. 파일당 10 MiB, 전체 20 MiB·10개 이내입니다. 별도 redirect 기반 업로드 완료 절차는 미지원입니다. 불명확한 전송 결과는 자동 재시도하지 않습니다.
227
+
228
+ ## 문제 해결
229
+
230
+ | 증상 | 확인할 항목 |
231
+ |---|---|
232
+ | `uv` 또는 `aside` 실행 실패 | 클라이언트 설정에 실행 파일 절대 경로 지정 |
233
+ | 로그인된 탭을 찾지 못함 | 선택한 브라우저에서 e-Class 로그인 후 탭 유지. 프로필 설정 확인 |
234
+ | CDP 연결 실패 | 디버깅 포트와 전용 프로필 확인, `doctor` 재실행 |
235
+ | 로그인·LearningX 요청 실패 | 다시 로그인하고 과목의 주차학습 화면을 연 뒤 재시도 |
236
+ | 새 다운로드 도구가 안 보임 | MCP 재연결 또는 새 세션 시작 |
237
+ | 원본 영상 다운로드 오류 | 서버 HTTP 500일 수 있음. 재생용 파일도 괜찮을 때만 대체 옵션 사용 |
238
+ | 영상이 `not open` | 현재 계정에 공개되지 않은 영상. 다운로드 불가 |
239
+ | 계획서 저장 실패 | 해당 과목에 OZ 뷰어와 PDF 저장 메뉴가 있는지 확인 |
240
+ | 직접 실행했는데 아무 일도 안 일어남 | stdio 서버가 클라이언트 요청을 기다리는 상태인지 확인 |
241
+
242
+ ## 개발·검증
243
+
244
+ ```sh
245
+ uv sync --frozen
246
+ uv run pytest -q
247
+ uv run ruff check src tests scripts
248
+ ```
249
+
250
+ CDP 연결 테스트는 임시 Chromium 프로필과 synthetic 사이트 응답으로 실행합니다. 실제 계정 테스트와 구분하며, macOS에서 로컬 검증하고 Linux/Windows 빌드는 CI에 구성했습니다. CI 구성 자체를 해당 운영체제 검증 완료로 간주하지 않습니다. 테스트 실행 방법은 [개발 안내](CONTRIBUTING.md)를 참고하세요.
251
+
252
+ wheel과 소스 배포본 생성:
253
+
254
+ ```sh
255
+ uv build --no-sources
256
+ uv run python scripts/check_dist.py
257
+ ```
258
+
259
+ [배포 절차와 참고 설계](docs/distribution.md)에 패키지 설치, 산출물 제외 규칙, 공개 게시 전 남은 설정을 정리했습니다. 실제 과제 제출은 검증하지 않았고, 원본 영상 서버의 HTTP 500 제한은 남아 있습니다.
260
+
261
+ - [실제 검증 결과와 제한](docs/verification.md)
262
+ - [구조와 FastMCP 선택 근거](docs/architecture.md)
263
+ - [인증·기능 분석 기록](analysis/authenticated-findings.md)
264
+
265
+ `analysis/`는 구현 전 조사 기록입니다. 현재 지원 범위는 이 README와 검증 기록을 기준으로 확인하세요. 분석 원본 JS·HTML은 Git에 포함하지 않아 새 checkout에는 없을 수 있습니다.
266
+
267
+
268
+ ## 라이선스
269
+
270
+ [CAU e-Class Noncommercial License 1.0](LICENSE)을 적용합니다. 개인 학습·비상업적 연구를 위한 사용·수정·재배포는 허용하며, 판매·유료 서비스·수익화 제품에 포함·사업 운영을 위한 사용은 금지합니다. 상업적 목적이라면 교육·비영리기관에도 예외를 두지 않습니다. 정확한 허용 범위와 조건은 LICENSE 원문을 따릅니다.
271
+
272
+ 프로젝트 전용 비상업 라이선스를 쓰는 **소스 공개(source-available)** 프로젝트이며 MIT 또는 OSI 오픈소스 라이선스가 아닙니다. 제3자 의존성은 각자의 라이선스를 유지합니다. 강의자료·대학 상표·사용자 데이터에 대한 권리는 이 라이선스에 포함되지 않습니다.
@@ -0,0 +1,246 @@
1
+ # CAU e-Class MCP
2
+
3
+ **비공식 중앙대학교 e-Class 도구 · 비상업적 사용만 허용 · 상업적 사용 금지**
4
+
5
+ 중앙대학교 e-Class의 강좌·공지·과제·마감일을 조회하고, 자료·계획서 PDF·영상을 내려받는 로컬 MCP 서버입니다. FastMCP 4.1.4를 사용하며 MCP 클라이언트와 stdio로 통신합니다.
6
+
7
+ ## 설치
8
+
9
+ Python 3.12 이상과 [uv](https://docs.astral.sh/uv/getting-started/installation/)가 필요합니다. **0.2.0 초기 배포판**입니다.
10
+
11
+ ### PyPI로 설치
12
+
13
+ ```sh
14
+ # Chrome·Edge 등 로컬 Chromium CDP 사용
15
+ uv tool install --python 3.12 'cau-eclass-mcp[cdp]==0.2.0'
16
+
17
+ # 설치 확인
18
+ eclass-mcp --version
19
+ ```
20
+
21
+ Aside만 사용한다면 `uv tool install --python 3.12 cau-eclass-mcp==0.2.0`으로 설치합니다.
22
+ [PyPI](https://pypi.org/project/cau-eclass-mcp/) · [GitHub Releases](https://github.com/givemethatsewon/cau-eclass-mcp/releases)
23
+
24
+ ### 전달받은 wheel로 설치
25
+
26
+ 저장소 checkout 없이 wheel 파일을 설치할 수 있습니다. 아래 경로는 전달받은 파일 위치로 바꿉니다.
27
+
28
+ ```sh
29
+ # Chrome·Edge 등 로컬 Chromium CDP 사용
30
+ uv tool install --python 3.12 --from /absolute/path/cau_eclass_mcp-0.2.0-py3-none-any.whl --with 'playwright>=1.60,<2' cau-eclass-mcp
31
+
32
+ # 설치 확인
33
+ uv tool run eclass-mcp --version
34
+ ```
35
+
36
+ Aside만 사용하는 경우 설치 명령의 `--with 'playwright>=1.60,<2'`를 생략합니다. `eclass-mcp`가 PATH에 없다면 아래 명령에서도 `uv tool run eclass-mcp`를 사용하거나 `uv tool update-shell` 후 터미널을 다시 엽니다.
37
+
38
+ ### 소스에서 실행
39
+
40
+ ```sh
41
+ uv sync --frozen --extra cdp
42
+ uv run eclass-mcp --help
43
+ ```
44
+
45
+ 이하의 `eclass-mcp` 명령은 소스 실행 시 `uv run eclass-mcp`로 바꾸면 됩니다. 설치된 Chrome·Edge에 연결만 하므로 `playwright install`로 별도 브라우저를 받을 필요는 없습니다.
46
+
47
+ ## 브라우저 선택과 로그인
48
+
49
+ | 방식 | 필요한 것 | 선택 |
50
+ |---|---|---|
51
+ | Chromium CDP | 전용 프로필로 remote debugging을 켠 Chrome·Edge 등 | `--browser cdp` |
52
+ | Aside | 실행 중인 로컬 Aside, `aside` CLI | `--browser aside` (기본값) |
53
+
54
+ ### Chromium CDP
55
+
56
+ [운영체제별 CDP 시작 가이드](docs/cdp.md)에 따라 브라우저를 실행합니다. macOS Chrome 예시:
57
+
58
+ ```sh
59
+ "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \
60
+ --remote-debugging-address=127.0.0.1 \
61
+ --remote-debugging-port=9222 \
62
+ --user-data-dir="$HOME/.cau-eclass/chrome-profile" \
63
+ https://eclass3.cau.ac.kr/
64
+ ```
65
+
66
+ 이 전용 프로필에서 직접 로그인하고 **주차학습 (모듈)** 화면을 한 번 연 뒤 탭을 유지합니다. 최초 로그인 이후에는 같은 프로필을 재사용합니다. 평소 프로필의 쿠키를 복사하지 않습니다.
67
+
68
+ ```sh
69
+ eclass-mcp --browser cdp --cdp-endpoint http://127.0.0.1:9222 doctor
70
+ ```
71
+
72
+ ### Aside
73
+
74
+ Aside에서 https://eclass3.cau.ac.kr/ 에 로그인하고 **주차학습 (모듈)** 화면을 한 번 엽니다. 탭과 Aside를 유지합니다.
75
+
76
+ ```sh
77
+ aside --help
78
+ eclass-mcp --browser aside doctor
79
+ ```
80
+
81
+ `doctor`는 프로필 조회로 연결·로그인을 검사하고 `ok: true/false`를 출력합니다. 이름·학번·쿠키는 출력하지 않습니다. 실패 시 종료 코드는 1입니다. 로그인 만료 시 선택한 브라우저에서 다시 로그인하세요.
82
+
83
+ ## MCP 클라이언트 연결
84
+
85
+ 설치 진단이 통과한 브라우저 설정으로 클라이언트 설정을 생성합니다. 이 명령은 설정을 **출력만** 하며 파일을 덮어쓰거나 클라이언트를 변경하지 않습니다.
86
+
87
+ ```sh
88
+ # Claude Desktop 또는 Cursor 형식
89
+ eclass-mcp --browser cdp --cdp-endpoint http://127.0.0.1:9222 config --client claude
90
+
91
+ # VS Code 형식
92
+ eclass-mcp --browser cdp config --client vscode
93
+
94
+ # Codex TOML 형식
95
+ eclass-mcp --browser cdp config --client codex
96
+ ```
97
+
98
+ Aside는 `--browser aside`로 바꾸고 CDP 옵션을 생략합니다. 필요하면 `--download-dir /absolute/path/downloads`도 함께 전달하세요. 공통 옵션은 `doctor`, `config`, `serve` 등의 명령 **앞에** 놓습니다.
99
+
100
+ 출력을 사용하는 클라이언트의 MCP 설정에 병합한 뒤 연결을 다시 시작합니다. 설정의 Python 경로는 설치 환경의 절대 경로이므로 패키지 설치 위치를 바꾸면 다시 생성하세요. `config`는 실제 제출을 항상 비활성화한 설정을 출력합니다. 형식별 예시는 [examples/](examples/)에 있습니다.
101
+
102
+ 서버만 직접 실행하려면:
103
+
104
+ ```sh
105
+ eclass-mcp --browser cdp serve
106
+ ```
107
+
108
+ 기본 명령도 `serve`입니다. 웹 포트를 제공하지 않고 stdio로 MCP 요청을 기다립니다. 사용자 브라우저는 서버 종료 후에도 유지됩니다.
109
+
110
+ ## 에이전트 스킬 설치 (선택)
111
+
112
+ 스킬은 과목 ID 선택, 마감일 해석, 원본/재생용 영상 구분, 제출 경계를 에이전트에 안내합니다. MCP 설치·브라우저 로그인을 대신하지 않습니다.
113
+
114
+ ```sh
115
+ mkdir -p ~/.agents/skills/cau-eclass
116
+ eclass-mcp skill > ~/.agents/skills/cau-eclass/SKILL.md
117
+ ```
118
+
119
+ 이미 같은 스킬이 있다면 덮어쓰기 전에 내용을 확인하세요. 클라이언트가 다른 스킬 디렉터리를 사용하면 경로를 바꿉니다. 저장소의 [SKILL.md](skills/cau-eclass/SKILL.md)를 직접 설치할 수도 있습니다.
120
+
121
+ ## 연결 확인과 사용
122
+
123
+ 연결한 에이전트에게 다음 순서로 요청합니다.
124
+
125
+ > eclass의 로그인 상태를 확인하고, 내 강좌 목록을 보여줘.
126
+
127
+ `get_session_status`와 `list_courses`로 확인할 수 있습니다. 현재 제공하는 도구는 **21개**입니다. 과목 ID는 강좌 목록에서, 과제·파일·영상 ID는 해당 목록이나 상세 응답에서 선택합니다.
128
+
129
+ 사용 예시:
130
+
131
+ - “컴퓨터그래픽스 공지를 이번 학기 시작일부터 오늘까지 조회해줘.”
132
+ - “빅데이터 과제와 마감일을 한국 시간으로 정리해줘.”
133
+ - “이 과목의 강의계획서를 PDF로 저장하고 본문을 읽어줘.”
134
+ - “이 첨부파일을 다운로드해줘.”
135
+ - “이 영상 원본을 다운로드해줘. 원본 서버가 실패하면 재생용 MP4로 받아도 돼.”
136
+ - “이 파일을 과제로 제출할 수 있는지 준비 검사만 해줘. 제출하지 마.”
137
+
138
+ 직접 도구를 호출하는 클라이언트에서는 다음 인자를 사용합니다. 숫자는 형식 예시이며 본인 계정의 ID로 바꿔야 합니다.
139
+
140
+ | 도구 | 인자 예시 |
141
+ |---|---|
142
+ | `list_announcements` | `{"course_id":123,"start_date":"2026-09-01","end_date":"2026-12-31"}` |
143
+ | `list_deadlines` | `{"course_id":123}` |
144
+ | `download_attachment` | `{"course_id":123,"file_id":456}` |
145
+ | `download_syllabus_pdf` | `{"course_id":123,"extract_text":true}` |
146
+ | `download_video_original` | `{"course_id":123,"item_id":789,"allow_playback_copy":false}` |
147
+ | `prepare_submission` | `{"course_id":123,"assignment_id":456,"files":["/absolute/path/work.pdf"]}` |
148
+
149
+ 도구 응답은 `observed_at`과 `result`로 구성됩니다. 목록의 `complete`·페이지 정보를 확인해 누락된 페이지가 없는지 판단하세요.
150
+
151
+ ## 다운로드
152
+
153
+ 기본 저장 위치는 사용자 홈의 `~/Downloads/cau-eclass/`입니다. `ECLASS_DOWNLOAD_DIR` 또는 `--download-dir`로 바꿀 수 있습니다. 결과에 로컬 절대 경로, 파일 크기, SHA-256이 반환되며 기존 파일을 덮어쓰지 않습니다.
154
+
155
+ | 대상 | 사용 방법과 제한 |
156
+ |---|---|
157
+ | Canvas 첨부 | `download_attachment`: Canvas file ID 사용, 최대 64 MiB. OCS 일반 주차자료와 LearningX 게시판 전용 첨부는 미지원 |
158
+ | 계획서 | `download_syllabus_pdf`: OZ의 Save → Adobe PDF로 전체 페이지 저장. `extract_text=true`가 기본값이며 페이지별 본문도 반환. `false`는 PDF만 저장. 64 MiB 초과 결과는 거부 |
159
+ | 영상 | `download_video_original`: 접근 가능한 Commons MP4 대상, 최대 1 GiB. `not_open` 영상은 거부 |
160
+
161
+ 계획서는 브라우저 인쇄본이 아닌 **OZ 네이티브 PDF 내보내기**입니다. OCR은 하지 않으며, 텍스트가 추출되지 않은 페이지가 있으면 `text_complete=false`를 반환합니다. `get_syllabus`는 별도로 HTML 본문과 뷰어 링크를 조회하는 도구입니다.
162
+
163
+ 실제 시험한 영상 원본 다운로드 주소는 학교 서버에서 HTTP 500을 반환했습니다. 기본 설정에서는 오류를 반환합니다. `allow_playback_copy=true`를 명시하면 플레이어의 정적 메타데이터에 제공된 MP4를 대신 내려받습니다. 이 경우 **`source=commons_playback_mp4`, `original=false`**로 반환합니다. 원본 다운로드 성공 시에는 `source=commons_original`, `original=true`입니다.
164
+
165
+ 영상 다운로드 과정에서 플레이어 스크립트·재생·진도 API를 실행하지 않습니다. 다운로드는 출석이나 학습 완료로 인정되지 않습니다.
166
+
167
+ ## 전체 도구
168
+
169
+ | 기능 | 도구 |
170
+ |---|---|
171
+ | 세션·강좌 | `get_session_status`, `list_courses` |
172
+ | 주차학습 | `list_learning_items` |
173
+ | 공지 | `list_announcements`, `get_announcement` |
174
+ | 과제·마감 | `list_assignments`, `get_assignment`, `list_deadlines`, `get_submission` |
175
+ | 계획서 | `get_syllabus`, `download_syllabus_pdf` |
176
+ | 게시판 | `list_boards`, `list_board_posts`, `get_board_post` |
177
+ | 그룹 | `list_my_groups`, `get_group_activity` |
178
+ | 다운로드 | `download_attachment`, `get_video_download_info`, `download_video_original` |
179
+ | 제출 준비·제출 | `prepare_submission`, `submit_assignment` |
180
+
181
+ ## 설정
182
+
183
+ | 환경 변수 | 기본값 | 용도 |
184
+ |---|---|---|
185
+ | `ECLASS_BROWSER` | `aside` | `aside` 또는 `cdp` 선택 |
186
+ | `ECLASS_CDP_ENDPOINT` | `http://127.0.0.1:9222` | 로컬 Chromium CDP 주소 |
187
+ | `ECLASS_ASIDE_BIN` | `aside` | Aside CLI 경로 |
188
+ | `ECLASS_ASIDE_PROFILE` | Aside 기본 프로필 | 로그인된 Aside 프로필 선택 |
189
+ | `ECLASS_DOWNLOAD_DIR` | `~/Downloads/cau-eclass` | 다운로드 폴더. 절대 경로 권장 |
190
+ | `ECLASS_ENABLE_SUBMISSION` | 비활성화 | 정확히 `1`일 때만 실험적 실제 제출 허용 |
191
+
192
+ 환경 변수는 MCP 클라이언트가 서버를 시작할 때 전달해야 합니다. 변경 후에는 연결을 다시 시작하세요. `.env` 파일을 자동으로 읽는 기능은 없습니다. 개인용 `mcp.json`, 다운로드, 세션·인증 파일은 Git에서 제외합니다.
193
+
194
+ ### 과제 제출
195
+
196
+ **실제 업로드·제출은 운영 검증되지 않은 실험 기능**입니다. 기본 설정 `ECLASS_ENABLE_SUBMISSION=0`을 유지하세요.
197
+
198
+ `prepare_submission`은 파일 해시·확장자·과제 잠금·기존 제출을 검사하고 유효기간 10분의 로컬 계획을 만듭니다. 파일을 업로드하지 않습니다. 실제 제출을 명시적으로 요청한 경우에만 설정을 `1`로 바꾸고, 준비 결과의 plan ID와 `SUBMIT <assignment_id>` 확인 문자열로 `submit_assignment`를 호출합니다.
199
+
200
+ Canvas 일반 파일 과제만 대상으로 하며 그룹·외부 originality 과제는 차단합니다. 파일당 10 MiB, 전체 20 MiB·10개 이내입니다. 별도 redirect 기반 업로드 완료 절차는 미지원입니다. 불명확한 전송 결과는 자동 재시도하지 않습니다.
201
+
202
+ ## 문제 해결
203
+
204
+ | 증상 | 확인할 항목 |
205
+ |---|---|
206
+ | `uv` 또는 `aside` 실행 실패 | 클라이언트 설정에 실행 파일 절대 경로 지정 |
207
+ | 로그인된 탭을 찾지 못함 | 선택한 브라우저에서 e-Class 로그인 후 탭 유지. 프로필 설정 확인 |
208
+ | CDP 연결 실패 | 디버깅 포트와 전용 프로필 확인, `doctor` 재실행 |
209
+ | 로그인·LearningX 요청 실패 | 다시 로그인하고 과목의 주차학습 화면을 연 뒤 재시도 |
210
+ | 새 다운로드 도구가 안 보임 | MCP 재연결 또는 새 세션 시작 |
211
+ | 원본 영상 다운로드 오류 | 서버 HTTP 500일 수 있음. 재생용 파일도 괜찮을 때만 대체 옵션 사용 |
212
+ | 영상이 `not open` | 현재 계정에 공개되지 않은 영상. 다운로드 불가 |
213
+ | 계획서 저장 실패 | 해당 과목에 OZ 뷰어와 PDF 저장 메뉴가 있는지 확인 |
214
+ | 직접 실행했는데 아무 일도 안 일어남 | stdio 서버가 클라이언트 요청을 기다리는 상태인지 확인 |
215
+
216
+ ## 개발·검증
217
+
218
+ ```sh
219
+ uv sync --frozen
220
+ uv run pytest -q
221
+ uv run ruff check src tests scripts
222
+ ```
223
+
224
+ CDP 연결 테스트는 임시 Chromium 프로필과 synthetic 사이트 응답으로 실행합니다. 실제 계정 테스트와 구분하며, macOS에서 로컬 검증하고 Linux/Windows 빌드는 CI에 구성했습니다. CI 구성 자체를 해당 운영체제 검증 완료로 간주하지 않습니다. 테스트 실행 방법은 [개발 안내](CONTRIBUTING.md)를 참고하세요.
225
+
226
+ wheel과 소스 배포본 생성:
227
+
228
+ ```sh
229
+ uv build --no-sources
230
+ uv run python scripts/check_dist.py
231
+ ```
232
+
233
+ [배포 절차와 참고 설계](docs/distribution.md)에 패키지 설치, 산출물 제외 규칙, 공개 게시 전 남은 설정을 정리했습니다. 실제 과제 제출은 검증하지 않았고, 원본 영상 서버의 HTTP 500 제한은 남아 있습니다.
234
+
235
+ - [실제 검증 결과와 제한](docs/verification.md)
236
+ - [구조와 FastMCP 선택 근거](docs/architecture.md)
237
+ - [인증·기능 분석 기록](analysis/authenticated-findings.md)
238
+
239
+ `analysis/`는 구현 전 조사 기록입니다. 현재 지원 범위는 이 README와 검증 기록을 기준으로 확인하세요. 분석 원본 JS·HTML은 Git에 포함하지 않아 새 checkout에는 없을 수 있습니다.
240
+
241
+
242
+ ## 라이선스
243
+
244
+ [CAU e-Class Noncommercial License 1.0](LICENSE)을 적용합니다. 개인 학습·비상업적 연구를 위한 사용·수정·재배포는 허용하며, 판매·유료 서비스·수익화 제품에 포함·사업 운영을 위한 사용은 금지합니다. 상업적 목적이라면 교육·비영리기관에도 예외를 두지 않습니다. 정확한 허용 범위와 조건은 LICENSE 원문을 따릅니다.
245
+
246
+ 프로젝트 전용 비상업 라이선스를 쓰는 **소스 공개(source-available)** 프로젝트이며 MIT 또는 OSI 오픈소스 라이선스가 아닙니다. 제3자 의존성은 각자의 라이선스를 유지합니다. 강의자료·대학 상표·사용자 데이터에 대한 권리는 이 라이선스에 포함되지 않습니다.