canvas-mcp-server
canvas-mcp-server
Canvas LMS REST API用のMCPサーバー。LLMにコース、課題、成績、提出物、お知らせ、ディスカッション、モジュール、ページ、ファイルへの読み取りアクセスを提供します。
20個のツール、すべて読み取り専用。
要件
Node.js 18+
任意の教育機関のCanvasアカウント
Canvas Web UIのAccount → Settings → New Access Tokenから取得したアクセストークン
インストール
npm install
npm run build設定
Canvasには共通のAPIホストはありません — 各教育機関が独自に運営しています。以下の2つの変数は必須です。
{
"mcpServers": {
"canvas": {
"command": "node",
"args": ["/absolute/path/to/canvas-mcp-server/dist/index.js"],
"env": {
"CANVAS_BASE_URL": "https://bcourses.berkeley.edu",
"CANVAS_ACCESS_TOKEN": "your-token-here"
}
}
}
}変数 | 必須 | デフォルト | 目的 |
| はい | — | あなたの教育機関のCanvasホスト。スキームを含み、末尾のパスはなし |
| はい | — | Account → Settings → New Access Token |
| いいえ |
| リクエストごとのタイムアウト |
| いいえ |
|
|
| いいえ |
| HTTPトランスポートのバインドアドレス |
| ホスト時 | — | エンドポイントを |
| いいえ | localhost + claude.ai | カンマ区切りのオリジン許可リスト |
ツールを対話的に確認する:
CANVAS_BASE_URL=https://your.canvas CANVAS_ACCESS_TOKEN=your-token npm run inspectデプロイ(Claude mobile / claude.aiコネクタ用)
ClaudeはデバイスからではなくAnthropicのクラウドからカスタムコネクタに接続するため、モバイルとclaude.aiではこれを公開HTTPS経由で到達可能にする必要があります。Claude CodeとClaude Desktopはその必要はありません — そこではstdioを使用してください。
1. パスシークレットを生成
openssl rand -hex 32サーバーはMCP_PATH_SECRETが設定されていない場合、非ループバックインターフェースでの起動を拒否します。Canvasトークンを保持する公開エンドポイントは、あなたのアカウントへのオープンプロキシになるためです。設定すると、エンドポイントは/mcp/<secret>に移動し、他のすべてのパスは404を返します — 間違ったシークレットも含めて、ホストを調べてもMCPサーバーが存在することを明かしません。
2. デプロイ
同梱のDockerfileとrailway.jsonは、Railway、Render、Flyでそのまま動作します。イメージはTRANSPORT=httpとHOST=0.0.0.0を設定し、非rootユーザーとして実行されます。プラットフォームのダッシュボードで3つの変数を設定してください:
変数 | 値 |
| あなたの教育機関のCanvasホスト |
| あなたのトークン |
| ステップ1の値 |
PORTはプラットフォームによって注入されます。/healthzは認証なしの死活プローブです。
3. 確認
curl -s https://your-app.up.railway.app/healthz4. コネクタを追加
claude.aiでブラウザ上で — コネクタはモバイルアプリからは追加できません:
Customize → Connectors → Add custom connector
URL:
https://your-app.up.railway.app/mcp/<secret>スマートフォンでチャットを開き、+ → Connectorsの下で有効にします。
そのURLはパスワードのように扱ってください。漏れた場合はMCP_PATH_SECRETをローテーションし、コネクタを再追加してください。
ツール
コース — canvas_list_courses, canvas_get_course, canvas_get_grades, canvas_list_enrollments, canvas_get_profile
課題 — canvas_list_assignments, canvas_get_assignment, canvas_get_submission, canvas_list_quizzes
プランナー — canvas_list_planner_items, canvas_list_upcoming, canvas_list_calendar_events
お知らせとディスカッション — canvas_list_announcements, canvas_list_discussions, canvas_get_discussion
コースコンテンツ — canvas_list_modules, canvas_list_module_items, canvas_list_pages, canvas_get_page, canvas_list_files
すべての読み取りツールはresponse_format: "markdown" | "json"を受け取ります。Markdownがデフォルトで、LLMが読むのに最適化されています。JSONは完全な構造化ペイロードです。structuredContentは形式に関係なく常に設定されます。
例
「今週の締め切りは?」
→ canvas_list_planner_itemsをend_dateを1週間後に設定して使用します。1回の呼び出しで全コースを対象とし、提出状態を報告します。デフォルトでは今日から開始するため、「何が遅れているか」を知りたい場合は、明示的に過去のstart_dateを渡してください。
「私の成績は?」
→ canvas_get_grades。1回の呼び出しで、すべてのアクティブなコースの現在のスコアと評定を取得します。
「今週教授たちは何を発表した?」
→ まずcanvas_list_coursesでIDを取得し、次にcanvas_list_announcementsにそれらをすべて一度に渡します。
「プロジェクト2で実際に何をすべき?」
→ search_term="project 2"を指定してcanvas_list_assignmentsでIDを取得し、次にcanvas_get_assignmentで完全な指示を取得します。
設計メモ
設計上読み取り専用。 すべてのツールはreadOnlyHint: trueとdestructiveHint: falseを持ち、クライアントには書き込みパスが公開されていません。Canvasトークンはアカウントの完全な権限を持ちます — 課題の提出、ディスカッションへの投稿、プロフィール設定の変更が可能です — そのためサーバーは意図的にそれらを公開しません。テストがこれを保証します: 書き込みツールが追加された場合、スイートは失敗します。
ベースURLは必須であり、デフォルトはありません。 シングルテナントAPIとは異なり、Canvasは教育機関ごとに1つのインスタンスを実行します。妥当なデフォルトは存在せず、ある学校のCanvasが発行したトークンは別の学校では無意味です。そのため、サーバーは後で401で誤解させるのではなく、起動時に失敗します。
ページネーションはヘッダーにあります。 CanvasはRFC 5988のLinkヘッダーで「次のページがあるか」を報告し、総数は返しません。これらのURLは不透明として文書化されているため、has_moreはヘッダーから読み取られ、page/per_pageは呼び出し側の制御として残ります — エージェントはスレッド化するカーソルではなく、単純なnext_pageを追跡します。
IDは文字列として要求されます。 CanvasのIDは64ビット整数であり、JavaScriptでは正確に表現できません。クライアントはAccept: application/json+canvas-string-idsを送信し、CanvasはすべてのIDを文字列として返すことでこれに応じます。そのため、IDはJSONラウンドトリップを無傷で通過します。
HTMLはモデルに到達する前に平坦化されます。 課題の説明、お知らせ、ディスカッションの投稿、ページはすべてHTMLとして保存されます。それをそのまま渡すとマークアップに膨大なコンテキストを消費するため、タグは改行になり、エンティティはデコードされ、長い本文はhtml_urlを保持して抜粋されます。
include[]は公開されていません。 Canvasには24のインクルードオプションがあり、リストエンドポイントと単一コースエンドポイントで異なり、そのほとんどはエージェントが使用しないフィールドを制御します。各ツールは必要なものを要求し、ユーザーが見るものを変更するトグルのみを公開します — include_syllabus、include_grades、include_submission。
コースIDはコンテキストコードに正規化されます。 一部のCanvasエンドポイントはコースを1234ではなくcourse_1234として扱います。両方の形式がどこでも受け入れられ変換されるため、エージェントはどのエンドポイントがどちらを必要とするかを覚える必要がありません。
エラーは次のアクションに解決されます。 404はそのリソースの有効なIDを生成するツールを指名します。403は権限の問題とレート制限の枯渇を区別します。Canvasはこれらを同じステータスで返すため紛らわしいです。401は、ある学校のCanvasのトークンが別の学校では機能しないことを指摘します。
2つのCanvasの癖はそのまま渡さずに処理されます。 コースがenrollments[].computed_current_scoreで報告する成績は、Enrollments APIがgrades.current_scoreと呼ぶ数値と同じです。両方が読み取られます。また、プランナーアイテムのsubmissionsフィールドは、提出可能なものがない場合、オブジェクトではなくブール値のfalseであり、読み取る前にチェックされます。
注意事項
お知らせはグローバルに一覧表示できません: Canvasは少なくとも1つのコースIDを必要とするため、
canvas_list_coursesを最初に実行する必要があります。canvas_list_discussionsはscopeフィルターをページネーション後に適用するため、フィルターされたページはper_pageより短くなることがありますが、結果の終わりではありません。Canvasは大きいとみなすモジュールのリスト応答からモジュールアイテムを省略します。
canvas_list_module_itemsがそれらを取得します。ページはタイトルではなくURLスラッグ(
week-1-reading)でアドレス指定されます。canvas_list_pagesはurlフィールドにスラッグを返します。カレンダーエンドポイントは最大10コースを受け入れ、残りを静かに無視します。
canvas_list_calendar_eventsは切り詰めるときに報告します。成績はインストラクターが投稿したもののみを反映し、最終成績を非表示に設定されたコースでは完全に省略されます。
プロジェクト構成
src/
├── index.ts # entry point, transport selection
├── constants.ts # enum values, limits, character limit
├── types.ts # interfaces for every Canvas entity
├── services/
│ └── canvas-client.ts # fetch wrapper, auth, Link pagination, error → guidance mapping
├── schemas/
│ ├── inputs.ts # Zod input schemas
│ └── outputs.ts # structuredContent schemas
├── formatters/
│ ├── response.ts # pagination, truncation, HTML flattening, format dispatch
│ └── entities.ts # per-entity markdown rendering
└── tools/
├── courses.ts
├── assignments.ts
├── planner.ts
├── announcements.ts
└── content.tsテスト
npm run build
npm test # 43 checks: MCP handshake, tools, pagination, formatting, errors (mocked API)
npm run test:http # 19 checks: config validation, path-secret gating, method handling, origins両方のスイートはローカルモックに対して実行されるため、トークンやネットワークアクセスは不要です。
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Gateway between LLM agents and world data through eight tools and a bundled endpoint catalog.
Read-only MCP server for ClassQuill, a tutoring-business-management platform.
Read-only MCP server for Muovi, Argentina's trust-first local services marketplace (6 tools).
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/RyK57/canvas-mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server