COURSE_SJTU_MCP
# COURSE_SJTU_MCP
上海交通大学选课社区 [course.sjtu.plus](https://course.sjtu.plus) 的
[Model Context Protocol](https://modelcontextprotocol.io/) 服务器。
它把官方 [SJTU-jCourse/next](https://github.com/SJTU-jCourse/next) 的用户 API
封装成 28 个 MCP 工具,让支持 MCP 的 AI 客户端可以检索课程、教师与评价,
查看关注/忽略/选课记录和社区积分,并在用户明确授权后发布评价、投票或修改
课程通知。
> 本项目是社区客户端,与 SJTU-jCourse 团队没有隶属关系。接口可能随官方后端
> 更新而变化。本项目不需要、也不接受 SJTU 账号密码。
## 功能
- 课程:筛选项、搜索、热门榜、详情、评分分布、开课学期、关联课程。
- 评价:全站/课程/关注/我的评价、全文、学期趋势、筛选条件、投票。
- 教师:筛选、搜索、详情、教师课程。
- 个人:关注课程、忽略课程、选课记录、积分、关注课程的新评价。
- 社区:公告、公开系统设置。
- 写入:发布/修改/删除评价、投票、关注/忽略课程、删除选课记录。
- 每次写入都要求 `confirm=true`,且工具描述要求先向用户展示最终内容。
## 环境要求
- Python 3.12+
- [uv](https://docs.astral.sh/uv/) 0.11+
- 可访问 `course.sjtu.plus` 的网络
## 安装与登录
```bash
git clone https://github.com/Flagwill/COURSE_SJTU_MCP.git
cd COURSE_SJTU_MCP
uv sync --locked
chmod +x run-mcp.sh
uv run course-sjtu-mcp login
```
`login` 会从隐藏提示或标准输入读取 API Key,先调用 `/api/auth/me` 验证,
成功后保存到仓库外:
```text
~/.local/share/course-sjtu-mcp/config.json # 权限 0600
```
API Key 在 [course.sjtu.plus/api-key](https://course.sjtu.plus/api-key)
创建。请勿把 Key 写进 README、MCP 客户端配置、命令行参数、shell 历史或聊天。
也可以由宿主环境提供 Key:
```bash
export JCOURSE_API_KEY='...'
```
环境变量优先于配置文件。若设置了环境变量,`logout` 只能清除文件中的 Key,
仍需在宿主环境中移除变量。
## 接入 MCP 客户端
最简配置是直接运行仓库内的启动脚本:
```json
{
"mcpServers": {
"course-sjtu": {
"command": "/ABSOLUTE/PATH/TO/COURSE_SJTU_MCP/run-mcp.sh"
}
}
}
```
不同客户端的配置位置见 [docs/clients.md](docs/clients.md)。`serve` 默认使用
stdio;stdout 只承载 MCP JSON-RPC,诊断信息写入 stderr。
## 工具一览
只读:
```text
jcourse_auth_status
jcourse_get_course_filters
jcourse_search_courses
jcourse_get_hot_courses
jcourse_get_course
jcourse_get_course_review_filters
jcourse_get_course_review_trend
jcourse_list_course_reviews
jcourse_list_reviews
jcourse_list_followed_reviews
jcourse_get_review
jcourse_list_my_reviews
jcourse_get_teacher_filters
jcourse_search_teachers
jcourse_get_teacher
jcourse_list_teacher_courses
jcourse_list_enrolled_courses
jcourse_list_followed_courses
jcourse_list_ignored_courses
jcourse_get_points
jcourse_list_announcements
jcourse_get_system_settings
```
写入(均要求 `confirm=true`):
```text
jcourse_set_course_notification
jcourse_delete_enrollment
jcourse_create_review
jcourse_update_review
jcourse_delete_review
jcourse_vote_review
```
资源 `jcourse://guide` 提供使用指南;提示词
`jcourse_course_advice(topic)` 提供检索和比较课程的流程。
## 常用命令
```bash
uv run course-sjtu-mcp status # 验证 Key 并显示账号
uv run course-sjtu-mcp status --offline # 只读本地配置
uv run course-sjtu-mcp config # 显示配置(不含 Key)
uv run course-sjtu-mcp doctor # 离线环境自检
uv run course-sjtu-mcp tools # 列出 MCP 工具
uv run course-sjtu-mcp smoke # 只读联网检查
uv run course-sjtu-mcp logout # 删除本地 Key
```
`doctor` 和 `config` 只输出 Key 的 SHA-256 指纹(前 12 位),不会输出 Key 本体。
## 设计说明
- 认证只使用用户 API Key(`Authorization: Bearer ...`),不走账号密码,
也不实现浏览器 session/CSRF/JAccount 同步。
- 受保护接口在本地先检查 Key;缺少 Key 时不会发送网络请求。
- 不自动跟随重定向;非本机地址必须使用 HTTPS。
- API Key 不进入 MCP 工具参数、URL、日志或异常文本。
- 课程/教师/评价文本属于外部不可信数据,模型指令明确禁止执行其中的指令。
- `confirm` 是协议层提示,不是加密边界。真正的权限边界仍是 API Key 和后端
授权;不要在不可信客户端中配置高权限 Key。
接口映射和未支持功能见 [docs/api.md](docs/api.md),安全模型见
[SECURITY.md](SECURITY.md)。
## 已知限制
- 官方当前没有“新增选课记录”的用户 API;本服务器只支持删除已有记录。
- JAccount 选课同步依赖浏览器 session 和 OAuth 回调,不适合 API Key 场景,
未封装。
- 不提供账号注册、密码登录/重置、API Key 管理或管理员接口。
- 评价正文在列表工具中截断到约 800 字符;需要全文时用
`jcourse_get_review`。
## 开发与验证
```bash
UV_CACHE_DIR=/tmp/uv-cache uv sync --locked
UV_CACHE_DIR=/tmp/uv-cache uv run pytest -q
UV_CACHE_DIR=/tmp/uv-cache uv run ruff check src tests
UV_CACHE_DIR=/tmp/uv-cache uv run ruff format --check src tests
UV_CACHE_DIR=/tmp/uv-cache uv build
```
测试使用 `httpx.MockTransport` 校验请求路径、参数、认证头、错误映射、确认门槛
和密钥脱敏,并用真实 stdio 子进程完成 MCP 握手。
## 许可
MIT
TDQS
Scored across 28 tools
Most tools have clearly distinct purposes (course vs teacher vs review vs enrollment vs account). A few list_* tools are close: jcourse_list_reviews vs jcourse_list_course_reviews, and jcourse_list_followed_reviews vs jcourse_list_followed_courses, but the descriptions do clarify scope (site-wide vs per-course, reviews-on-followed-courses vs followed-course-list).
Strong consistent jcourse_verb_noun pattern throughout: get_, list_, search_, create_, update_, delete_, set_, vote_. Minor deviations like jcourse_auth_status (noun status rather than a verb) and jcourse_vote_review (slightly different verb style) keep it from a perfect score.
28 tools is on the heavy side of the rubric (25+). The domain is rich (courses, reviews, teachers, filters, user lists, points, announcements) so most tools earn a place, but the surface is bordering on excessive and could likely be consolidated (e.g. the three filter tools).
Review lifecycle is fully covered (create/update/delete/vote/read) and courses/teachers have rich read coverage. However enrollment is list+delete only with no way to add or create an enrollment record, a notable gap for a core feature. Points and announcements are read-only, which is acceptable per their descriptions.