Skip to main content
Glama

Canvas MCP Server

by plyght
client.ts9.49 kB
import axios, { AxiosInstance } from "axios"; export interface CanvasConfig { baseUrl: string; accessToken: string; } export interface Course { id: number; name: string; course_code: string; workflow_state: string; enrollment_term_id?: number; start_at?: string; end_at?: string; } export interface Assignment { id: number; name: string; description: string; due_at?: string; points_possible?: number; submission_types: string[]; course_id: number; html_url: string; } export interface Submission { id: number; assignment_id: number; user_id: number; grade?: string; score?: number; submitted_at?: string; workflow_state: string; late: boolean; } export interface Conversation { id: number; subject: string; workflow_state: string; last_message: string; last_message_at: string; message_count: number; participants: Array<{ id: number; name: string; avatar_url?: string; }>; } export interface CalendarEvent { id: number; title: string; description?: string; start_at: string; end_at?: string; all_day: boolean; context_code: string; html_url: string; } export interface GradingPeriod { id: number; title: string; start_date: string; end_date: string; } export interface Enrollment { id: number; user_id: number; course_id: number; type: string; role: string; enrollment_state: string; grades?: { current_score?: number; current_grade?: string; final_score?: number; final_grade?: string; }; } export class CanvasClient { private client: AxiosInstance; private config: CanvasConfig; constructor(config: CanvasConfig) { this.config = config; this.client = axios.create({ baseURL: config.baseUrl, headers: { Authorization: `Bearer ${config.accessToken}`, "Content-Type": "application/json", }, }); } async getCurrentUser() { const response = await this.client.get("/api/v1/users/self"); return response.data; } async getCourses(enrollmentState = "active") { const response = await this.client.get<Course[]>("/api/v1/courses", { params: { enrollment_state: enrollmentState, include: ["term", "total_scores"], }, }); return response.data; } async getCourse(courseId: number) { const response = await this.client.get<Course>(`/api/v1/courses/${courseId}`); return response.data; } async getAssignments(courseId: number) { const response = await this.client.get<Assignment[]>( `/api/v1/courses/${courseId}/assignments`, { params: { per_page: 100, }, } ); return response.data; } async getAssignment(courseId: number, assignmentId: number) { const response = await this.client.get<Assignment>( `/api/v1/courses/${courseId}/assignments/${assignmentId}` ); return response.data; } async getSubmission(courseId: number, assignmentId: number) { const response = await this.client.get<Submission>( `/api/v1/courses/${courseId}/assignments/${assignmentId}/submissions/self`, { params: { include: ["submission_comments", "rubric_assessment"], }, } ); return response.data; } async submitAssignment( courseId: number, assignmentId: number, submissionData: { submission_type: string; body?: string; url?: string; file_ids?: number[]; } ) { const response = await this.client.post( `/api/v1/courses/${courseId}/assignments/${assignmentId}/submissions`, { submission: submissionData } ); return response.data; } async getConversations(scope: "inbox" | "unread" | "starred" | "sent" | "archived" = "inbox") { const response = await this.client.get<Conversation[]>("/api/v1/conversations", { params: { scope, per_page: 50, include_all_conversation_ids: false, }, }); return response.data; } async getConversation(conversationId: number) { const response = await this.client.get(`/api/v1/conversations/${conversationId}`, { params: { auto_mark_as_read: true, }, }); return response.data; } async createConversation( recipients: string[], subject: string, body: string, courseId?: number, groupConversation: boolean = false ) { const response = await this.client.post("/api/v1/conversations", { recipients, subject, body, context_code: courseId ? `course_${courseId}` : undefined, group_conversation: groupConversation, force_new: true, }); return response.data; } async replyToConversation(conversationId: number, body: string) { const response = await this.client.post(`/api/v1/conversations/${conversationId}/add_message`, { body, }); return response.data; } async markConversationAsRead(conversationId: number) { const response = await this.client.put(`/api/v1/conversations/${conversationId}`, { conversation: { workflow_state: "read", }, }); return response.data; } async markConversationAsUnread(conversationId: number) { const response = await this.client.put(`/api/v1/conversations/${conversationId}`, { conversation: { workflow_state: "unread", }, }); return response.data; } async starConversation(conversationId: number) { const response = await this.client.put(`/api/v1/conversations/${conversationId}`, { conversation: { starred: true, }, }); return response.data; } async unstarConversation(conversationId: number) { const response = await this.client.put(`/api/v1/conversations/${conversationId}`, { conversation: { starred: false, }, }); return response.data; } async archiveConversation(conversationId: number) { const response = await this.client.put(`/api/v1/conversations/${conversationId}`, { conversation: { workflow_state: "archived", }, }); return response.data; } async deleteConversation(conversationId: number) { const response = await this.client.delete(`/api/v1/conversations/${conversationId}`); return response.data; } async getCalendarEvents(startDate?: string, endDate?: string) { const response = await this.client.get<CalendarEvent[]>("/api/v1/calendar_events", { params: { type: "event", start_date: startDate, end_date: endDate, per_page: 100, }, }); return response.data; } async getUpcomingAssignments() { const response = await this.client.get("/api/v1/users/self/upcoming_events"); return response.data; } async getGrades(courseId: number) { const response = await this.client.get<Enrollment[]>( `/api/v1/courses/${courseId}/enrollments`, { params: { user_id: "self", type: ["StudentEnrollment"], include: ["current_grading_period_scores"], }, } ); return response.data; } async getAllGrades() { const courses = await this.getCourses(); const gradesPromises = courses.map(async (course) => { try { const grades = await this.getGrades(course.id); return { course, grades: grades[0]?.grades || {}, }; } catch { return { course, grades: {}, }; } }); return Promise.all(gradesPromises); } async getCourseTodos(courseId: number) { const response = await this.client.get(`/api/v1/courses/${courseId}/todo`); return response.data; } async getAllTodos() { const response = await this.client.get("/api/v1/users/self/todo"); return response.data; } async getCourseModules(courseId: number) { const response = await this.client.get(`/api/v1/courses/${courseId}/modules`, { params: { include: ["items"], per_page: 100, }, }); return response.data; } async getAnnouncements(courseId?: number) { const contextCodes = courseId ? [`course_${courseId}`] : undefined; const response = await this.client.get("/api/v1/announcements", { params: { context_codes: contextCodes, per_page: 50, }, }); return response.data; } async getFiles(courseId?: number) { const endpoint = courseId ? `/api/v1/courses/${courseId}/files` : "/api/v1/users/self/files"; const response = await this.client.get(endpoint, { params: { per_page: 100, }, }); return response.data; } async downloadFile(fileId: number) { const response = await this.client.get(`/api/v1/files/${fileId}`); return response.data; } async getQuizzes(courseId: number) { const response = await this.client.get(`/api/v1/courses/${courseId}/quizzes`, { params: { per_page: 100, }, }); return response.data; } async getQuizSubmission(courseId: number, quizId: number) { const response = await this.client.get( `/api/v1/courses/${courseId}/quizzes/${quizId}/submissions/self` ); return response.data; } async searchUsers(courseId: number, searchTerm: string) { const response = await this.client.get(`/api/v1/courses/${courseId}/users`, { params: { search_term: searchTerm, per_page: 50, }, }); return response.data; } }

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/plyght/canvas-mcp'

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