sjtu-canvas-mcp
Provides MCP tools to read SJTU Canvas data, download course files, and access video/subtitle resources without authentication simulation.
README
SJTU Canvas Assistant
一个从零搭建的本地 Python CLI 框架,用 Canvas Access Token 读取上海交通大学 Canvas 数据,下载课程文件,并生成可供后续 Codex/MCP 使用的本地索引。
默认 Canvas 主站:
https://oc.sjtu.edu.cn
第一版不模拟 jAccount 登录,不保存密码,不自动提交作业。课程、文件、作业等基础数据走 Canvas API;视频模块通过 Canvas Access Token 发起 sessionless LTI,再只读调用 SJTU 视频 API。
参考、致谢与许可证
本项目阅读并借鉴了学长项目 SJTU Canvas Helper 的接口方向。该参考项目使用 MIT License,版权声明为 Copyright (c) 2025 Zihong Lin。本项目同样以 MIT License 开源,并保留对参考项目的明确链接和致谢。
- Canvas 基础数据走
/api/v1/...和 Bearer token。 - 课程列表包含
teachers和term。 - 文件、文件夹、模块、作业分别通过 Canvas API 拉取,并处理分页。
- SJTU 视频/字幕/PPT 回放通过 Canvas 外部工具 8329 接入。当前实现优先使用 Canvas
sessionless_launchAPI 发起 LTI,不需要模拟 jAccount 表单登录。 - MCP Server 直接复用本项目的
CanvasClient、CourseSyncer、SJTUVideoClient和索引模型,而不是重新写一套访问逻辑。
本项目不会照搬 Tauri 桌面 App,只提供可扩展的本地 CLI、Python 模块和 MCP stdio server。如果未来直接复制或改写参考项目中的实质代码,应继续保留其原 MIT 许可证声明。
安装
建议使用虚拟环境:
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -U pip
python -m pip install -e ".[dev]"
安装后会得到两个等价命令:
sjtu-canvas --help
sjtu-canvas-assistant --help
也可以不安装脚本,直接运行:
python -m sjtu_canvas_assistant.cli --help
创建 Canvas Access Token
在 SJTU Canvas 页面中创建个人访问令牌:
- 打开
https://oc.sjtu.edu.cn。 - 登录后进入左侧
Account/账户。 - 打开
Settings/设置。 - 找到
Approved Integrations/已批准的集成。 - 点击
New Access Token/新建访问令牌。 - 填写用途,例如
sjtu-canvas-assistant-local,按需设置过期时间。 - 复制生成的 token。Canvas 通常只显示一次,请妥善保存。
不要把 token 写进代码或提交到 git。
配置
复制示例配置:
cp .env.example .env
编辑 .env:
CANVAS_TOKEN=你的 Canvas Access Token
CANVAS_BASE_URL=https://oc.sjtu.edu.cn
CANVAS_DATA_DIR=data
# 可选调试项;通常留空,由 video 命令自动通过 Canvas LTI 换取。
SJTU_VIDEO_TOKEN=
SJTU_VIDEO_COURSE_ID=
.env 已被 .gitignore 忽略。
也可以临时用环境变量:
export CANVAS_TOKEN="你的 Canvas Access Token"
常用命令
验证 token 并显示当前用户:
sjtu-canvas whoami
列出当前账号可访问课程:
sjtu-canvas courses
sjtu-canvas courses --active-only
输出 JSON:
sjtu-canvas courses --json
列出某门课的全部核心信息:
sjtu-canvas course 12345
分别列出文件、文件夹、模块、作业:
sjtu-canvas files 12345
sjtu-canvas folders 12345
sjtu-canvas modules 12345
sjtu-canvas assignments 12345
列出和查看自己已经提交过的作业:
sjtu-canvas submissions 12345
sjtu-canvas submissions 12345 --all
sjtu-canvas submission 12345 ASSIGNMENT_ID
下载自己提交过的作业附件:
sjtu-canvas download-submissions 12345
sjtu-canvas download-submissions 12345 --assignment-id ASSIGNMENT_ID
sjtu-canvas download-submissions 12345 --latest-only
默认会保留 Canvas submission history 中各次提交的附件,路径形如:
data/课程名 [课程ID]/submissions/作业名 [作业ID]/attempt-1/文件名
这几个命令只读取和下载你自己的提交记录,不会提交、修改或评论作业。JSON/MCP 输出会隐藏附件下载 URL。
下载前预检文件数量、总大小和本地路径:
sjtu-canvas plan 12345
sjtu-canvas plan 12345 --output data --json
按课程下载文件并生成索引:
sjtu-canvas download 12345
指定输出目录:
sjtu-canvas download 12345 --output data
只生成索引,不下载缺失文件:
sjtu-canvas index 12345
查看视频/字幕模块状态:
sjtu-canvas video-status 12345
sjtu-canvas video status
列出某门课的视频:
sjtu-canvas video list 12345
sjtu-canvas video list 12345 --json
读取某个视频的播放元数据:
sjtu-canvas video info 12345 VIDEO_ID
导出字幕为 SRT:
sjtu-canvas video subtitle 12345 VIDEO_ID
sjtu-canvas video subtitle 12345 VIDEO_ID --output data/subtitles/example.srt
读取 PPT 回放切片元数据:
sjtu-canvas video ppt 12345 VIDEO_ID
下载 PPT 回放图片并合成 PDF:
sjtu-canvas video ppt-export 12345 VIDEO_ID
sjtu-canvas video ppt-export 12345 VIDEO_ID --output data/ppt/example
sjtu-canvas video ppt-export 12345 VIDEO_ID --no-pdf
下载与索引行为
下载时会尽量保持 Canvas 文件夹结构。例如 Canvas 中的:
course files/课件/Week 1/intro.pdf
会保存为:
data/课程名 [课程ID]/课件/Week 1/intro.pdf
路径和文件名会做安全清洗,避免 / \ : * ? " < > | 等跨平台非法字符。
如果本地已存在同大小文件,默认跳过,不重复下载。若本地同名文件大小不同,会保留原文件并为新下载文件追加 __canvas_文件ID 后缀以避免覆盖。
每次 download 或 index 会生成:
data/课程名 [课程ID]/course_index.json
data/课程名 [课程ID]/course_index.md
索引包含:
- 课程基本信息
- 文件、文件夹、模块、作业
- 本地下载路径和状态
- 文件更新时间
- 视频/字幕/PPT 回放的只读接入状态
- MCP Server 工具接口状态
错误处理
已覆盖的常见错误:
- token 缺失:提示设置
CANVAS_TOKEN - 401:token 无效或过期
- 403:无权限访问课程或资源
- 404:课程、文件夹或资源不存在
- 网络超时/连接失败
- 文件名非法字符清洗
- 下载文件大小不匹配
- 本地文件名冲突
错误信息不会打印 token。
视频、字幕、PPT 回放
当前已经接入视频读取和本地导出能力。认证流程是:
- 使用 Canvas Access Token 调用
/api/v1/courses/{course_id}/external_tools/sessionless_launch?id=8329&launch_type=course_navigation。 - 打开 Canvas 返回的一次性 LTI launch URL。
- 解析 LTI/OIDC 表单并提交到
v.sjtu.edu.cn。 - 从跳转 URL 中取得
tokenId。 - 调用
getAccessTokenByTokenId换取 SJTU 视频 API token 和视频系统courId。 - 后续视频 API 请求使用临时视频 token。
支持的只读功能:
video list: 调用findVodVideoList列出课程视频。video info: 调用getVodVideoInfos获取播放元数据。默认表格不会打印播放 URL;JSON/MCP 输出会递归脱敏 token/cookie/session 字段,并默认隐藏播放/下载 URL。video subtitle: 调用transfer/translate/detail获取字幕并生成 SRT。video ppt: 调用vod-analysis/query-ppt-slice-es获取 PPT 切片元数据。
支持的本地导出功能:
video ppt-export: 下载 PPT 回放切片图片,默认合成为ppt.pdf。- 已存在的图片会默认跳过;加
--force会重新下载并重新生成 PDF。 - 加
--no-pdf可以只下载图片,不合成 PDF。
字幕来源是 SJTU 视频系统返回的数据。本工具不做本地语音识别,也不调用大模型生成字幕,只把接口返回的字幕行转换成 .srt。当前接口没有暴露字幕作者或生成器字段,因此不能可靠区分是平台自动转写、教师上传,还是后续修订版本。
暂不实现:
- 视频二进制下载。
- 任何作业提交或自动交互。
根据参考项目实现,底层端点是:
- Canvas sessionless launch:
/api/v1/courses/{course_id}/external_tools/sessionless_launch - LTI 初始化:
https://v.sjtu.edu.cn/jy-application-canvas-sjtu/oidc/login_initiations - token 交换:
https://v.sjtu.edu.cn/jy-application-canvas-sjtu/lti3/getAccessTokenByTokenId - 调用
findVodVideoList列出视频。 - 调用
getVodVideoInfos获取播放地址。 - 调用
transfer/translate/detail获取字幕。 - 调用
vod-analysis/query-ppt-slice-es获取 PPT 切片元数据。
这条链路不读取 jAccount 密码。命令执行期间会使用 Canvas 返回的一次性 launch URL 和临时视频 token,错误信息会去掉 query/token,避免泄露凭据。
MCP 接入
项目已经把能力拆成可复用模块:
CanvasClient: Canvas API、分页、错误处理、下载流CourseSyncer: 课程元数据拉取、下载规划、本地同步SJTUVideoClient: 视频 LTI 认证、视频列表、详情、字幕、PPT 切片元数据PPTAssetExporter: PPT 回放图片下载和 PDF 合成indexer: JSON/Markdown 索引models: 稳定数据模型
本地 MCP stdio server 已提供,启动命令:
sjtu-canvas-mcp
也可以通过主 CLI 启动:
sjtu-canvas mcp
在支持 MCP 的客户端中可配置为:
{
"mcpServers": {
"sjtu-canvas": {
"command": "/Users/hebing/Documents/Canvas/.venv/bin/sjtu-canvas-mcp",
"cwd": "/Users/hebing/Documents/Canvas"
}
}
}
cwd 建议指向项目根目录,这样 server 能读取本地 .env。不要把 .env 提交到 git。
当前暴露的工具:
get_current_userlist_coursesget_courselist_course_fileslist_course_folderslist_course_moduleslist_course_assignmentslist_my_submissionsget_my_submissionget_course_bundleplan_course_downloadgenerate_course_indexdownload_course_filesdownload_my_submission_filesvideo_statusresolve_video_authlist_course_videosget_video_infoget_video_subtitleget_video_ppt_slicesdownload_video_ppt
作业相关能力只读;提交记录工具只下载你自己已提交的附件,不开放提交、评论或改分。视频导出工具只写本地文件,不自动发布或上传。
开发验证
python -m pytest
sjtu-canvas --help
sjtu-canvas video-status
sjtu-canvas video --help
printf '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"manual","version":"0"}}}\n{"jsonrpc":"2.0","id":2,"method":"tools/list"}\n' | sjtu-canvas-mcp
如果没有真实 token,也可以运行上述 mock 测试和 help 命令验证框架。
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。