canvas-mcp-server
canvas-mcp-server
Canvas LMS REST API용 MCP 서버입니다. LLM이 강좌, 과제, 성적, 제출물, 공지사항, 토론, 모듈, 페이지, 파일을 읽을 수 있게 해줍니다.
20개의 도구, 모두 읽기 전용입니다.
요구 사항
Node.js 18+
모든 기관의 Canvas 계정
Canvas 웹 UI에서 계정 → 설정 → 새 액세스 토큰으로 발급한 액세스 토큰
설치
npm install
npm run build구성
Canvas에는 공유 API 호스트가 없습니다 — 각 기관이 자체 호스트를 운영합니다. 아래 두 변수는 모두 필수입니다.
{
"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 호스트, 스킴 포함, 후행 경로 없음 |
| 예 | — | 계정 → 설정 → 새 액세스 토큰 |
| 아니요 |
| 요청당 타임아웃 |
| 아니요 |
|
|
| 아니요 |
| HTTP 전송 바인드 주소 |
| 호스팅 시 | — | 엔드포인트를 |
| 아니요 | localhost + claude.ai | 쉼표로 구분된 출처 허용 목록 |
도구를 대화형으로 검사:
CANVAS_BASE_URL=https://your.canvas CANVAS_ACCESS_TOKEN=your-token npm run inspect배포 (Claude 모바일 / claude.ai 커넥터용)
Claude는 사용자 기기가 아닌 Anthropic의 클라우드에서 사용자 지정 커넥터에 연결하므로, 모바일과 claude.ai에서는 이 서버를 공개 HTTPS로 접근 가능하게 해야 합니다. Claude Code와 Claude Desktop은 그렇지 않으므로 대신 stdio를 사용하세요.
1. 경로 비밀번호 생성
openssl rand -hex 32MCP_PATH_SECRET이 설정되지 않은 상태에서 루프백이 아닌 인터페이스에서 서버가 시작되지 않습니다. Canvas 토큰을 보유한 공개 엔드포인트는 계정에 대한 개방형 프록시가 되기 때문입니다. 설정하면 엔드포인트가 /mcp/<secret>으로 이동하고 다른 모든 경로는 404를 반환합니다 — 잘못된 비밀번호도 포함되므로 호스트를 탐색해도 MCP 서버가 존재한다는 사실이 드러나지 않습니다.
2. 배포
포함된 Dockerfile과 railway.json은 Railway, Render, Fly에서 그대로 작동합니다. 이미지는 TRANSPORT=http와 HOST=0.0.0.0을 설정하고 비루트 사용자로 실행됩니다. 플랫폼 대시보드에서 세 가지 변수를 설정하세요:
변수 | 값 |
| 기관의 Canvas 호스트 |
| 토큰 |
| 1단계의 값 |
PORT는 플랫폼에서 주입됩니다. /healthz는 인증 없는 활성 프로브입니다.
3. 확인
curl -s https://your-app.up.railway.app/healthz4. 커넥터 추가
claude.ai에서 브라우저로 — 모바일 앱에서는 커넥터를 추가할 수 없습니다:
사용자 지정 → 커넥터 → 사용자 지정 커넥터 추가
URL:
https://your-app.up.railway.app/mcp/<secret>휴대폰에서 채팅을 열고 + → 커넥터에서 활성화
이 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를 일주일 후로 설정. 한 번의 호출로 모든 강좌를 아우르고 제출 상태를 보고합니다. 기본적으로 오늘부터 시작하므로 "내가 뭘 밀렸지"를 보려면 명시적으로 이전 start_date를 전달하세요.
"내 성적은?"
→ canvas_get_grades. 한 번의 호출로 모든 활성 강좌의 현재 점수와 학점을 가져옵니다.
"교수님들이 이번 주에 공지한 게 뭐지?"
→ canvas_list_courses로 id를 얻은 다음, canvas_list_announcements에 모두 한 번에 전달.
"프로젝트 2를 위해 실제로 해야 할 일은?"
→ canvas_list_assignments에 search_term="project 2"로 id를 얻은 다음, canvas_get_assignment로 전체 지침을 확인.
설계 노트
구조적으로 읽기 전용. 모든 도구는 readOnlyHint: true와 destructiveHint: false를 가지며, 클라이언트에는 쓰기 경로가 노출되지 않습니다. Canvas 토큰은 계정의 전체 권한을 지닙니다 — 과제 제출, 토론 게시, 프로필 설정 변경이 가능합니다 — 따라서 서버는 의도적으로 그 어떤 것도 노출하지 않습니다. 테스트가 이를 보장합니다: 쓰기 도구가 추가되면 테스트 스위트가 실패합니다.
기본 URL은 필수이며 기본값이 없습니다. 단일 테넌트 API와 달리 Canvas는 기관별로 인스턴스를 운영합니다. 합리적인 기본값이 없으며, 한 학교의 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를 문자열로 반환하여 JSON 왕복에서 ID가 손상되지 않습니다.
HTML은 모델에 도달하기 전에 평탄화됩니다. 과제 설명, 공지사항, 토론 게시물, 페이지는 모두 HTML로 저장됩니다. 이를 그대로 전달하면 마크업에 엄청난 컨텍스트가 소모되므로 태그는 줄바꿈으로, 엔티티는 디코딩되고, 긴 본문은 html_url을 유지한 채 발췌됩니다.
include[]는 노출되지 않습니다. Canvas에는 24개의 include 옵션이 있으며, 목록과 단일 강좌 엔드포인트 간에 다르고, 대부분 에이전트가 사용할 필요가 없는 필드를 제어합니다. 각 도구는 필요한 것만 요청하고 사용자가 볼 수 있는 것을 변경하는 토글만 표시합니다 — include_syllabus, include_grades, include_submission.
강좌 ID는 컨텍스트 코드로 정규화됩니다. 일부 Canvas 엔드포인트는 강좌를 1234가 아닌 course_1234로 주소 지정합니다. 두 형식 모두 모든 곳에서 허용되고 변환되므로 에이전트는 어떤 엔드포인트가 어떤 형식을 원하는지 기억할 필요가 없습니다.
오류는 다음 행동으로 해결됩니다. 404는 해당 리소스에 유효한 ID를 생성하는 도구를 알려줍니다. 403은 권한 문제와 소진된 속도 제한을 구분합니다 — Canvas는 혼란스럽게도 같은 상태 코드로 둘 다 반환합니다. 401은 한 학교의 Canvas 토큰이 다른 학교에서 작동하지 않음을 지적합니다.
두 가지 Canvas 특이점은 전달하지 않고 처리합니다. 강좌가 enrollments[].computed_current_score로 보고하는 성적은 Enrollments API가 grades.current_score라고 부르는 숫자와 동일합니다. 둘 다 읽습니다. 그리고 플래너 항목의 submissions 필드는 제출 가능한 것이 없을 때 객체가 아닌 부울 false이며, 읽기 전에 확인됩니다.
주의 사항
공지사항은 전역으로 나열할 수 없습니다: Canvas는 최소 하나의 강좌 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두 스위트 모두 로컬 목(mock)에 대해 실행되므로 토큰이나 네트워크 접근이 필요 없습니다.
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