帆布代理
连接人工智能助手(谷歌的Gemini CLI、Claude Code和Claude Desktop)的MCP服务器 指令画布LMS。教师和管理员可以通过自然语言管理课程、作业、成绩等。
想安装Canvas Agent吗? 请按照以下设置指南进行操作: **** --不需要技术背景。
______________________________________________________________________
建筑
Canvas Agent作为 三 主控程序 来自一个npm包的服务器,因意图而分裂。默认情况下,安装向导会注册所有三个;想要保存上下文的用户可以从MCP配置中删除admin或extra。
AI client (Claude Code / Claude Desktop / Gemini CLI)
├─ spawns canvas-agent (core, 80 tools — daily teaching/grading)
├─ spawns canvas-agent-admin (18 tools — course/section/enrollment lifecycle)
└─ spawns canvas-agent-extras (36 tools — outcomes, groups, pages, files, messaging, …)
└─ MCP stdio transport
└─ Canvas REST API (bearer token auth)这三个箱子共享一个导入图和一个每门课程的保险库,因此匿名令牌在服务器之间保持一致。核心还包括 describe_canvas_mcps 工具,这样AI就可以在所需工具未加载时告诉用户要安装哪个其他箱子。
| 组件 | 路径 | 角色 |
|---|---|---|
| 核心MCP入口点 | src/servers/core.ts | 79个日常教学/评分工具+ describe_canvas_mcps 元工具 |
| 管理员MCP入口点 | src/servers/admin.ts | 18门课程/部分/注册生命周期工具 |
| 附加MCP入口点 | src/servers/extras.ts | 36个结果/组/页面/文件/消息/迟到政策/经典测验工具 |
| CLI调度程序 | src/cli.ts | npx canvas-agent 启动核心服务器; setup/reveal/vault-gc 子命令保持在同一个垃圾箱中。两个额外的垃圾箱(canvas-agent-admin, canvas-agent-extras)直接指向他们的服务器文件。 |
| Canvas API客户端 | src/canvas-client.ts | 带有自动分页功能的瘦取纸包装(canvasAll 对于平面阵列端点, canvasAllWrapped 为了 {key: [...], linked: {…}} 形状)和速率限制回退。通过匿名器传输每个响应→ 名称检测器→ 返回前先进行沙箱操作。 |
| 工具模块 | src/tools/*.ts | 每个Canvas域一个文件。每个bucket注册器导出混合bucket文件(例如。 registerCoursesCore + registerCoursesAdmin);单桶文件导出一个(例如。 registerAssignmentsCore). |
| 隐私管道 | src/anonymizer.ts, src/name-detector.ts, src/sandbox.ts, src/vault.ts | MCP边界的三阶段编辑:令牌交换结构化PII字段,编辑自由文本中的学生姓名,用提示注入分隔符包装不受信任的内容。每门课程跳马跟踪角色(学生/教师/未知);教师是免税的。地图生活在 ~/.canvas-agent/vault/. |
| 安装向导 | src/setup.ts | 交互式CLI,用于验证凭据、检测Claude Code/Destop/GGemini CLI,并注册所有三个v2容器。 |
| 刀具布线断言线束 | scripts/assert-tool-routing.mjs | 通过MCP SDK启动所有三个拆分服务器,并断言每个服务器都完全暴露其bucket(80/18/36),没有跨服务器名称冲突。运行通过 npm test. |
| 着陆地点 | docs/ | 带有最终用户设置指南的静态GitHub Pages网站 |
工具模块
| 模块 | 文件 | v2容器 | 盖子 |
|---|---|---|---|
| 课程介绍 | courses.ts | core+admin | core:列出课程、术语、作业组、模块、评分期。管理员:创建/更新/删除/结束/重置/复制课程、导航选项卡。 |
| 作业 | assignments.ts | core | CRUD分配、批量更新日期 |
| 提交材料 | submissions.ts | core | 列出/下载提交内容,下载讨论条目 |
| 评分 | grading.ts | 核心+额外 | 核心:成绩/批量成绩/岗位/隐藏、失踪和可评分的学生。附加:迟到政策、评分标准。 |
| Rubrics | rubrics.ts | 核心 | CRUD量规,跨作业/课程复制,与显示开关关联,链接到结果,查看/编辑/删除评估 |
| 成果 | outcomes.ts | extrases | 列出结果/组、结果结果、掌握汇总 |
| 模块 | modules.ts | core | CRUD模块和模块项,发布模块 |
| 页面 | pages.ts | extra | CRUD页面、首页、页面修订 |
| 讨论 | discussions.ts | core | CRUD讨论和批量更新(下载条目存在于submissions.ts中) |
| 测验(经典) | quizzes.ts | extrases | 列出/获取/更新经典测验 |
| 新测验 | new-quizzes.ts | core | 列出/CRUD新测验、测验项目、住宿,生成测验报告 |
| 日历 | calendar.ts | core | CRUD日历事件 |
| 文件 | files.ts | extras | 列出/获取/更新/删除文件、文件夹、配额 |
| 报名人数 | enrollments.ts | core+admin | core:列出学生/部门/用户,获取个人资料。管理员:交叉列表,创建/更新/删除部分,注册/删除用户,移动学生。 |
| 沟通 | communication.ts | 核心+附加 | 核心:提交后的评论。附加功能:发送消息、创建公告。 |
| 团体 | groups.ts | extra | 组集、组、成员资格、自动分发 |
| 分析 | analytics.ts | 核心+附加 | 核心:课程/学生活动、作业分析、学生总结。附加:消息数据。 |
| 日程安排 | scheduling.ts | 核心+附加 | 核心:分配日期、批量更新、覆盖、进度概述。附加:经典的测验日期。 |
| Meta | meta.ts | 核心 | describe_canvas_mcps --向AI解释三种MCP架构 |
从v1.x迁移
v2将v1单MCP表面划分为核心/管理/附加。如果你现有的配置只是 canvas-agent,您将继续工作,但无法访问任何移出核心的内容。将相关bin添加到MCP配置中:
{
"mcpServers": {
"canvas-agent": { "command": "npx", "args": ["-y", "canvas-agent"] },
"canvas-agent-admin": { "command": "npx", "args": ["-y", "canvas-agent-admin"] },
"canvas-agent-extras": { "command": "npx", "args": ["-y", "canvas-agent-extras"] }
}
}安装向导(npx canvas-agent setup)默认情况下注册所有三个——再次运行它是最简单的升级路径。
Tool → bin查找(按字母顺序)
如果你在v1中使用了一个工具,这个表告诉你它在哪个v2 bin中。这里没有列出的工具在 canvas-agent (核心)。
| 工具 | v2容器 |
|---|---|
add_user_to_group | canvas-agent-extras |
auto_distribute_unassigned | canvas-agent-extras |
conclude_course | canvas-agent-admin |
copy_course_content | canvas-agent-admin |
create_announcement | canvas-agent-extras |
create_course | canvas-agent-admin |
create_folder | canvas-agent-extras |
create_group | canvas-agent-extras |
create_group_set | canvas-agent-extras |
create_page | canvas-agent-extras |
create_section | canvas-agent-admin |
crosslist_section | canvas-agent-admin |
decrosslist_section | canvas-agent-admin |
delete_course | canvas-agent-admin |
delete_enrollment | canvas-agent-admin |
delete_file | canvas-agent-extras |
delete_page | canvas-agent-extras |
delete_section | canvas-agent-admin |
enroll_user | canvas-agent-admin |
get_file | canvas-agent-extras |
get_file_quota | canvas-agent-extras |
get_front_page | canvas-agent-extras |
get_grading_standards | canvas-agent-extras |
get_late_policy | canvas-agent-extras |
get_outcome | canvas-agent-extras |
get_outcome_rollups | canvas-agent-extras |
get_page | canvas-agent-extras |
get_quiz | canvas-agent-extras |
get_student_messaging_data | canvas-agent-extras |
list_course_files | canvas-agent-extras |
list_course_tabs | canvas-agent-admin |
list_folders | canvas-agent-extras |
list_group_categories | canvas-agent-extras |
list_groups | canvas-agent-extras |
list_outcome_groups | canvas-agent-extras |
list_outcome_results | canvas-agent-extras |
list_outcomes | canvas-agent-extras |
list_page_revisions | canvas-agent-extras |
list_pages | canvas-agent-extras |
list_quizzes | canvas-agent-extras |
list_term_courses | canvas-agent-admin |
move_student_to_section | canvas-agent-admin |
remove_user_from_group | canvas-agent-extras |
reset_course_content | canvas-agent-admin |
send_message | canvas-agent-extras |
set_late_policy | canvas-agent-extras |
update_course_navigation | canvas-agent-admin |
update_course_settings | canvas-agent-admin |
update_enrollment_state | canvas-agent-admin |
update_file | canvas-agent-extras |
update_page | canvas-agent-extras |
update_quiz | canvas-agent-extras |
update_quiz_dates | canvas-agent-extras |
update_section | canvas-agent-admin |
保管库、匿名器和显示CLI没有变化——没有数据迁移。您还可以要求AI“描述画布代理的MCP”,它将通过 describe_canvas_mcps 核心工具。
发展
git clone https://github.com/hughsibbele/Canvas-Agent.git
cd Canvas-Agent
npm install
cp .env.example .env # add your CANVAS_API_URL and CANVAS_API_TOKEN
npm run build
node dist/cli.js # start the core MCP server (default canvas-agent bin)
node dist/servers/admin.js # start admin server directly
node dist/servers/extras.js # start extras server directly
node dist/cli.js setup # run the setup wizard
npm test # boot all three servers and assert routingnpm run dev 开始 tsc --watch 用于迭代工具模块。
添加工具
- 确定它属于哪个bucket(核心/管理/附加)——有关现有工具的基本原理,请参阅V2_BUILD_PLAN.md。
- 添加
server.tool(...)注册到适当的register*Core/register*Admin/register*Extras功能在src/tools/.ts.创建新的域名文件+注册商(如果需要);从文件导出并在匹配中导入/调用src/servers/.ts. - 更新中的路由清单
scripts/assert-tool-routing.mjs如果工具落在admin或extra中。 npm test以验证。- 重建(
npm run build)并重新启动MCP客户端以获取新工具。
每个工具模块都遵循相同的模式——定义Zod输入模式并将其注册到 server.tool()。查看模板的任何现有模块。
隐私和安全管道
每个Canvas响应都流经一个三级编校管道 canvas-client.ts 在它到达AI助手之前:
- 结构化PII匿名器 (
src/anonymizer.ts).浏览响应并将学生姓名、电子邮件、登录ID、SIS ID等交换为不透明令牌(Student_)在每个用户形状的物体上。将每个用户记录在由Canvas user_id键入的每门课程库中,并带有派生角色标签。 - 自由文本名称检测器 (
src/name-detector.ts).扫描自由文本字段(讨论正文、提交散文、评论、描述、文件名)以查找任何已知学生的全名或可排序表单("Jane Doe"/"Doe, Jane")并用学生现有的令牌替换匹配项。使用支持Unicode的边界,因此名称带有撇号(O'Brien)和连字符(Smith-Jones)正确匹配。当然,当vault发生变化时,正则表达式会被缓存并失效。 - 即时注入沙盒 (
src/sandbox.ts).用每个进程的随机数分隔符包裹同一组自由文本字段(…)因此,下游的法学硕士将学生撰写的内容视为数据,而不是指令。随机数是过程随机的——学生无法猜测它会伪造一个结束标签并“突破”沙盒。
在写入路径上, rehydrateText 将令牌交换回真实名称,并剥离LLM可能回显的任何沙盒标记,因此评论和公告会正确地发出,不会将保护标记泄漏到Canvas中。
角色——教师保持可读性
vault将每个用户标记为 student, teacher,或 unknown。角色来源于注册上下文(enrollments[].type, grader_* / assessor / edited_by / graded_by 字段位置)并单调合并(teacher > student > unknown,从不降级)。 知名教师完全跳过标记化 --他们的真实姓名会传递给人工智能。这使“我给这个评分了吗?”这样的工作流程保持正常,避免了将员工视为隐私保护的对象。
CLI工具
canvas-agent reveal Student_a4f2c1 # decode a token (any course)
canvas-agent reveal Student_a4f2c1 --course 42 # single course
canvas-agent reveal --all --course 42 # dump every entry for a course
canvas-agent vault-gc # dry-run report of orphan vault rows
canvas-agent vault-gc --apply # actually prune them
canvas-agent vault-gc --course 42 --verbose # scope + show student-by-student detailvault-gc 清理1.5.0之前版本下累积的孤立行 id-vs-user_id bug,其中每个讨论条目/提交/评论都会生成一个由条目id而不是用户id键入的幻影保险库行。默认模式为模拟运行。
整个管道可以通过以下方式禁用 CANVAS_AGENT_ANONYMIZE=0 (关闭匿名化和自由文本名称检测)或 CANVAS_AGENT_SANDBOX=0 (仅关闭提示注射包装)。
值得了解的极限
search_term查询命中了Canvas的实名索引。如果AI发送令牌,Canvas将一无所获——离线显示并搜索user_id相反。download_submissions按设计将提交附件(Word文档、PDF等)作为原始字节写入磁盘。这些文件包含真实的学生姓名和提交内容;它们会保留在您的本地计算机上,但不会被编辑。- 自由文本名称检测器只匹配全名和可排序的形式。只有名字和姓氏的引用不会发生变化(故意——常见英语单词上有太多误报)。
- 帐户级终结点(
/accounts/*,顶级/conversations列表)不包含每门课程的上下文,因此每门课程库不适用于它们。
画布API gotchas
在添加或更新工具时,有几件事值得了解:
- 分级期 范围分数和提交到一个学期/学期。通过
grading_period_id到/courses/{id}/enrollments(每个周期的回报current_score/current_grade)以及/courses/{id}/students/submissions(仅返回该期间的提交内容)。没有它,你会得到累积数据,这对于每学期成绩册重置的一年制课程来说是错误的。 /courses/{id}/grading_periods返回包装好的响应 —{"grading_periods": [...], "meta": {...}}--所以canvasAll分页助手无法将其变平。请使用canvas并手动打开包装(参见list_grading_periods在tools/courses.ts).- 分析端点不支持
grading_period_id—get_student_summaries,get_course_assignment_analytics,以及get_student_assignment_data始终返回生命周期总计。对于学期范围的数据,请直接使用grading_period_id.
链接
- npm: 帆布代理
- 安装指南:
- 画布API文档: canvas.instructure.com/doc/api
许可证
麻省理工学院
