Skip to main content
Glama

Codex Canvas MCP

一个可移植的本地 MCP 服务器,让兼容客户端能够读取 Canvas,并且仅在通过多项独立安全检查之后,才能创建常见的课程内容。

安全模型

  • 在本地凭据设置完成后,Canvas 读取功能默认可用。

  • 写入功能默认禁用。

  • 每次内容写入都需要启用本地策略、精确的按课程允许列表匹配、精确的确认文本,以及 MCP 客户端中的批准。

  • 图片上传增加了载荷门控:只有位于一个已配置的受信任文件夹内、由本地拥有的 PNG、JPEG 或 WebP 文件,且大小不超过 10 MiB,才能被发送。

  • 不存在通用的 Canvas 写入工具。

  • 凭据保存在 1Password 中,并可选择保存在 macOS 钥匙串中。它们不应出现在此仓库或客户端配置中。

每个内容工具都被标记为变更性和破坏性操作,以便兼容客户端可以要求批准。本地服务器还会拒绝调用,除非其精确确认与所请求的操作匹配,例如 APPROVE CANVAS MODULE WRITE course <course_id>

评分量规创建接受同源的 Canvas 作业 URL、作业模块项目 URL,或包含 assignment_id 查询参数的课程 URL。在课程和作业解析完成后,查询字符串和片段将被忽略。该 URL 永远不会绕过课程策略:其课程 ID 仍必须被明确列入允许列表,并且评分量规创建需要 APPROVE CANVAS RUBRIC WRITE course <course_id>。该工具拒绝替换现有的作业评分量规,要求为每个标准和评级提供描述,并要求评分量规分数与作业分数一致。

Related MCP server: CoursePack Local MCP Server

包含内容

工具

能力

默认状态

canvas_get_current_user

读取已认证的个人资料

可用

canvas_list_modules

读取一个课程的模块和项目

可用

canvas_read_api

GET 一个规范化的 Canvas API v1 路径

可用

canvas_get_write_policy

检查本地策略状态

可用

canvas_upload_image

从已配置的受信任文件夹上传一个已验证的图片

已阻止

canvas_write_page

创建或更新一个页面

已阻止

canvas_create_module

创建一个模块

已阻止

canvas_create_module_item

将一个内容项目放入模块

已阻止

canvas_create_assignment

创建一个作业

已阻止

canvas_create_assignment_rubric

从 Canvas URL 创建并附加一个作业评分量规

已阻止

canvas_create_discussion

创建一个讨论

已阻止

canvas_create_classic_quiz

创建一个经典测验

已阻止

canvas_create_classic_quiz_question

向经典测验添加一个问题

已阻止

canvas_delete_page

删除一个页面

已阻止

canvas_delete_assignment

删除一个作业

已阻止

canvas_delete_discussion

删除一个讨论

已阻止

canvas_delete_classic_quiz

删除一个经典测验

已阻止

canvas_delete_module

删除一个模块及其项目放置

已阻止

设置新 Mac

先决条件:Python 3.11 或更高版本、1Password CLI、一个只能读取预期 Canvas 凭据项目的 1Password 服务账户,以及一个具有适合您工作的最低权限的 Canvas API 令牌。

  1. 克隆并安装到隔离环境中:

    git clone https://github.com/mrchris-ai/codex_canvas_mcp.git
    cd codex_canvas_mcp
    python3 -m venv .venv
    . .venv/bin/activate
    python -m pip install --upgrade pip
    python -m pip install -e .
  2. 创建一个 1Password 项目,其隐藏字段包含 Canvas API 令牌。仅授予服务账户对包含该项目的保险库/项目的读取权限。记录保险库名称、项目名称或 ID,以及隐藏字段标签;不要将其值放入此仓库。

  3. 选择一种服务账户令牌传递方式:

    • 对于短期 shell 会话,通过您的本地密钥启动器向 MCP 服务器进程提供 OP_SERVICE_ACCOUNT_TOKEN

    • 在 macOS 上,将该令牌存储在钥匙串中,并配置非机密查找标签。示例命令(它会安全地提示输入;不要将令牌放在命令行上):

      security add-generic-password -U -s "your-service-label" -a "your-account-label" -w
  4. 使用以下非机密值配置服务器进程:

    变量

    用途

    CANVAS_BASE_URL

    Canvas HTTPS 源,例如 https://school.instructure.com

    CANVAS_OP_VAULT

    1Password 保险库名称或 ID

    CANVAS_OP_ITEM

    Canvas 凭据项目名称或 ID

    CANVAS_OP_FIELD

    隐藏令牌字段标签;默认为 credential

    CANVAS_KEYCHAIN_SERVICE

    未使用 OP_SERVICE_ACCOUNT_TOKEN 时的 macOS 钥匙串服务标签

    CANVAS_KEYCHAIN_ACCOUNT

    未使用 OP_SERVICE_ACCOUNT_TOKEN 时的 macOS 钥匙串账户标签

    CANVAS_IMAGE_UPLOAD_ROOT

    允许图片上传的唯一本地文件夹的绝对路径

  5. 仅测试协议和安全门控,不联系 Canvas 或读取凭据:

    python -m unittest discover -s tests -v
    printf '%s\n' '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | python -m canvas_mcp
  6. 将 stdio 服务器添加到 Codex。项目级形式为:

    [mcp_servers.canvas]
    command = "/absolute/path/to/codex_canvas_mcp/.venv/bin/python"
    args = ["-m", "canvas_mcp"]
    
    [mcp_servers.canvas.env]
    CANVAS_BASE_URL = "https://school.instructure.com"
    CANVAS_OP_VAULT = "your-vault"
    CANVAS_OP_ITEM = "your-item"
    CANVAS_OP_FIELD = "credential"
    CANVAS_KEYCHAIN_SERVICE = "your-service-label"
    CANVAS_KEYCHAIN_ACCOUNT = "your-account-label"
    CANVAS_IMAGE_UPLOAD_ROOT = "/absolute/path/to/reviewed/canvas-images"

    将其放入受信任项目的 .codex/config.toml 或您的个人 Codex 配置中。不要添加机密值。更改 MCP 配置后重新启动或打开新任务,然后在请求 Canvas 数据之前验证列出的工具。

ChatGPT 兼容性

此仓库为 Codex 和其他支持本地 stdio MCP 的客户端实现了一个本地 stdio MCP 服务器。当前的 ChatGPT 自定义应用不会直接连接到本地 stdio 服务器。OpenAI 当前的指导是通过 Secure MCP Tunnel 暴露私有本地 MCP(或部署经过审查的远程 MCP 端点),具体取决于套餐和工作区管理员可用性。不要将此进程直接暴露到公共互联网。

在尝试 ChatGPT 设置之前,请参阅 ChatGPT 中的开发者模式和 MCP 应用;可用性和批准行为可能会发生变化。

启用内容创建工具

除非特定任务需要,否则保持写入功能关闭。

  1. config/write-policy.example.json 复制到仓库之外的位置。

  2. 仅添加批准用于内容创建的精确 Canvas 课程 ID。

  3. enabled 设置为 true 并限制文件权限:

    chmod 600 /absolute/private/path/write-policy.json
  4. CANVAS_WRITE_POLICY=/absolute/private/path/write-policy.json 添加到 MCP 服务器环境。

  5. 重新启动客户端并调用 canvas_get_write_policy 以验证生效的策略。

  6. 对于每次内容写入,审查精确的目标和载荷。提供特定于操作的确认短语,并在客户端中批准变更性操作。

  7. 任务完成后再次禁用该策略。

如果变量缺失、文件不存在、权限比 0600 更宽松、写入被禁用,或课程不在允许列表中,服务器将拒绝写入。

启用图片上传

图片上传使用相同的本地写入策略和精确课程允许列表,外加 CANVAS_IMAGE_UPLOAD_ROOT。该工具拒绝相对路径、符号链接、该根目录之外的文件、非当前用户拥有的文件、不支持的图片类型、二进制签名与扩展名不一致的文件,以及大于 10 MiB 的文件。精确确认为 APPROVE CANVAS IMAGE UPLOAD course <course_id>

Canvas 使用文档化的三步上传交换:通过已认证的 API 初始化课程文件,将图片(不带 Canvas 访问令牌)发送到 Canvas 返回的 HTTPS 存储 URL,然后对返回的同源 Canvas 完成位置进行认证。该工具随后读取 /api/v1/courses/<course_id>/files/<file_id> 并检查 MIME 类型和大小,然后返回一个持久的课程预览路径。它永远不会返回存储签名或文件下载验证器 URL。

当前的创建边界

此项目是此 Mac 上受支持聊天所使用的共享本地 Canvas MCP 的事实来源。在正常的策略和批准门控之后,它可以创建页面、模块和模块项目、作业和作业评分量规、讨论,以及带问题的经典测验。它还提供针对页面、作业、讨论、经典测验和模块的资源特定删除工具;删除模块会移除其项目放置,但不会移除底层课程内容。其唯一的本地文件能力是上述受载荷门控的图片上传器。通用文件上传、New Quizzes 以及账户/课程管理仍然不受支持。

有关实现和端到端验证记录,请参阅 docs/2026-08-06-content-authoring-extension.md。 有关图片上传威胁模型和验证记录,请参阅 docs/2026-08-16-image-upload-extension.md

开发

python -m pip install -e .
python -m unittest discover -s tests -v
python -m compileall -q src tests

测试模拟网络和凭据边界。请参阅 AGENTS.md 了解贡献者必须保留的不变量,并参阅 ROADMAP.md 了解有意推迟的管理功能。

F
license - not found
A
quality
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • MCP server for the Inistate platform: module discovery, entry management, and activity submission.

  • A MCP server built for developers enabling Git based project management with project and personal…

  • An MCP server for deep research or task groups

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/mrchris-ai/codex_canvas_mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server