内容
# 科学東京LMS MCP
東京科学大学(Science Tokyo)的LMS(学习管理系统)操作MCP(模型上下文协议)服务器。通过MCP客户端(如Claude)作为工具调用,实现课件下载、作业截止日期确认等功能。
> [!NOTE]
> 如果您只是想引入并开始使用该工具(针对实验室成员),请参阅 [`docs/USAGE.md`](docs/USAGE.md)。本README主要总结了方针、内部结构和开发流程。
> [!WARNING]
> 本工具**前提是个人学习使用**。自动访问大学系统可能会违反使用规定。在使用前,请确认Science Tokyo的使用规定,并通过限制访问频率(如缓存、低频访问)等方式节制使用。
## 目标和基础
- **目标LMS:** Science Tokyo LMS (`https://lms.s.isct.ac.jp/<年度>/`)
- **基础:** **Moodle** (已确认)。每个年度的路径不同(例如:`/2025/`)。
- **方式:** Moodle **Web Services REST API** + 移动令牌认证。使用官方API而不是浏览器遍历(爬虫)可以保证稳定性和高速率。
- 数据获取层 (`client/moodle_client.py`) 已实现,但**未使用实际令牌进行操作确认**(请在以下 `science-tokyo-lms-login` 中获取后验证)。
## 认证方针(MFA必填前提)
Science Tokyo受SAML2 SSO (`isct.ex-tic.com` / MFA必填)保护。因此,不能使用密码进行令牌颁发。相反,使用与**Moodle移动应用相同的启动流程**。
```bash
# 仅首次:浏览器将打开,因此请完成SSO登录(包括MFA)-> 获取移动令牌并保存在keyring中
uv run science-tokyo-lms-login
```
获取的令牌保存在keyring(如果不可用则为 `.auth/wstoken`,两者都已 `.gitignore`)中,从此以后,无需浏览器即可调用Web Services API。如果令牌过期,请再次执行上述命令。
## 设置
```bash
uv sync # 同步依赖关系
uv run playwright install chromium # 获取使用的浏览器(chromium / firefox / webkit)
cp .env.example .env # 根据需要编辑(年度、浏览器等)
```
## 配置(`.env`)
主要的配置项(环境变量 `STLMS_*`,可在 `.env` 中指定)。
| 变量 | 默认值 | 说明 |
|---|---|---|
| `STLMS_LMS_BASE_URL` | `.../2025/` | Moodle的基础URL(每个年度路径不同) |
| `STLMS_BROWSER` | `chromium` | 用于获取令牌的浏览器(`chromium` / `firefox` / `webkit`) |
| `STLMS_TOKEN_BACKEND` | `auto` | 令牌保存方式(`auto` / `keyring` / `file`) |
| `STLMS_WSTOKEN` | (无) | 直接指定令牌时使用(优先级最高) |
> 如果无法使用keyring(密码存储),请指定 `STLMS_TOKEN_BACKEND=file`,则令牌将保存到 `.auth/wstoken`(已 `.gitignore`,权限为0600)。
## 启动
```bash
uv run science-tokyo-lms-mcp # 在stdio上启动MCP服务器
```
MCP客户端(例如Claude Desktop / Claude Code)应按以下方式注册。
```json
{
"mcpServers": {
"science-tokyo-lms": {
"command": "uv",
"args": ["run", "--directory", "/path/to/ScienceTokyoLMS-mcp", "science-tokyo-lms-mcp"]
}
}
}
```
## 提供工具
| 工具 | 说明 |
|---|---|
| `list_courses` | 正在履修的课程列表 |
| `list_materials(course_id)` | 课程资料列表 |
| `download_material(course_id, material_id, dest_dir?)` | 下载课程资料 |
| `list_assignments(course_id?)` | 作业和截止日期列表 |
| `get_upcoming_deadlines(days=7)` | 获取即将到来的截止日期 |
| `list_announcements(course_id?)` | 公告/停课信息(通知)列表 |
> 由于作业提交状态需要单独的API,目前 `submitted` 始终为 `false`(未来计划使用 `mod_assign_get_submission_status` 支持)。
## 主要的Moodle Web Services函数支持
| 工具 | Web Services函数 |
|---|---|
| `list_courses` | `core_webservice_get_site_info` + `core_enrol_get_users_courses` |
| `list_materials` | `core_course_get_contents` |
| `list_assignments` | `mod_assign_get_assignments` |
| `list_announcements` | `mod_forum_get_forums_by_courses` + `mod_forum_get_forum_discussions` |
## 目录结构
```
src/science_tokyo_lms_mcp/
├── server.py # FastMCP服务器(入口点)
├── login.py # 初始令牌获取CLI
├── config.py # 配置(环境变量STLMS_*)
├── models.py # 数据模型
├── auth/
│ ├── session.py # Playwright持久会话管理
│ └── token.py # 移动令牌获取和存储(keyring)
├── client/
│ ├── base.py # LMSClient协议
│ ├── moodle_client.py # Moodle Web Services实现(默认)
│ └── playwright_client.py # 爬虫方式的备用方案
└── tools/ # MCP工具(courses / materials / deadlines / announcements)
```
## 开发
```bash
uv run ruff format . # 格式化
uv run ruff check . # Lint检查
uv run ty check # 类型检查
uv run pytest # 测试
```
## 安全
- **不提交**认证信息、cookie、令牌、下载材料(已 `.gitignore`)。
- 不在代码或配置文件中存储密码,SSO使用持久化配置文件,令牌则交由keyring管理。
- 建议**私有化运行**此存储库。