agentsclimarketplace

Canvas bulk grading

Skill vishalsachdev/canvas-mcp/skills/canvas-bulk-grading

Bulk grading workflows for Canvas LMS assignments using rubrics. Covers single grading, batch grading, and code execution strategies with safety-first dry runs.From its SKILL.md

Install
npx -y skills add vishalsachdev/canvas-mcp --skill canvas-bulk-grading

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

SKILL.md

6.9 KB, ~1.6k tokens by cl100k_base, as published. Nobody here has run it

Canvas Bulk Grading

Grade Canvas LMS assignments efficiently using rubric-based workflows. This skill requires the Canvas MCP server to be running and authenticated with an instructor or TA token.

Prerequisites

  • Canvas MCP server running and connected
  • Authenticated with an educator (instructor/TA) Canvas API token
  • Assignment must exist and have submissions to grade
  • Rubric must already be created in Canvas and associated with the assignment (Canvas API cannot reliably create rubrics -- use the Canvas web UI for that)

Workflow

Step 1: Gather Assignment and Rubric Information

Before grading, retrieve the assignment details and its rubric criteria.

get_assignment_details(course_identifier, assignment_id)

Then get the rubric. Use get_assignment_rubric_details if the rubric is already linked to the assignment, or list_all_rubrics to browse all rubrics in the course:

get_assignment_rubric_details(course_identifier, assignment_id)
list_all_rubrics(course_identifier)
get_rubric_details(course_identifier, rubric_id)

Record the criterion IDs (often prefixed with underscore, e.g., _8027) and rating IDs from the rubric response. These are required for rubric-based grading.

Step 2: List Submissions

Retrieve all student submissions to determine how many need grading:

list_submissions(course_identifier, assignment_id)

Note the user_id for each submission and the workflow_state (submitted, graded, pending_review). Count the submissions that need grading to determine which strategy to use.

Step 3: Choose a Grading Strategy

Use this decision tree based on the number of submissions to grade:

How many submissions need grading?
|
+-- 1-9 submissions
|   Use grade_with_rubric (one call per submission)
|
+-- 10-29 submissions
|   Use bulk_grade_submissions (concurrent batch processing)
|   Set max_concurrent: 5, rate_limit_delay: 1.0
|   ALWAYS run with dry_run: true first
|
+-- 30+ submissions OR custom grading logic needed
    Use execute_typescript with bulkGrade function
    99.7% token savings -- grading logic runs locally
    ALWAYS run with dry_run: true first

Strategy A: Single Grading (1-9 submissions)

Call grade_with_rubric once per student:

grade_with_rubric(
  course_identifier,
  assignment_id,
  user_id,
  rubric_assessment: {
    "criterion_id": {
      "points": <number>,
      "rating_id": "<string>",    // optional
      "comments": "<string>"      // optional per-criterion feedback
    }
  },
  comment: "Overall feedback"     // optional
)

Strategy B: Bulk Grading (10-29 submissions)

Always dry run first. Build the grades dictionary mapping each user ID to their grade data, then validate before submitting:

bulk_grade_submissions(
  course_identifier,
  assignment_id,
  grades: {
    "user_id_1": {
      "rubric_assessment": {
        "criterion_id": {"points": 85, "comments": "Good analysis"}
      },
      "comment": "Overall feedback"
    },
    "user_id_2": {
      "grade": 92,
      "comment": "Excellent work"
    }
  },
  dry_run: true,          // VALIDATE FIRST
  max_concurrent: 5,
  rate_limit_delay: 1.0
)

Review the dry run output. If everything looks correct, re-run with dry_run: false.

Strategy C: Code Execution (30+ submissions)

For large classes or custom grading logic, use execute_typescript to run grading locally. This avoids loading all submission data into the conversation context.

execute_typescript(code: `
  import { bulkGrade } from './canvas/grading/bulkGrade.js';

  await bulkGrade({
    courseIdentifier: "COURSE_ID",
    assignmentId: "ASSIGNMENT_ID",
    gradingFunction: (submission) => {
      // Custom grading logic runs locally -- no token cost
      const notebook = submission.attachments?.find(
        f => f.filename.endsWith('.ipynb')
      );

      if (!notebook) return null; // skip ungraded

      return {
        points: 100,
        rubricAssessment: { "_8027": { points: 100 } },
        comment: "Graded via automated review"
      };
    }
  });
`)

Use search_canvas_tools("grading", "signatures") to discover available TypeScript modules and their function signatures before writing code.

Token Efficiency

The three strategies have very different token costs:

StrategyWhenToken CostWhy
grade_with_rubric1-9 submissionsLowFew round-trips, small payloads
bulk_grade_submissions10-29 submissionsMediumOne call with batch data
execute_typescript30+ submissionsMinimalGrading logic runs locally; only the code string is sent. 99.7% savings vs loading all submissions into context

The key insight: as submission count grows, sending grading logic to the server (code execution) is far cheaper than bringing all submission data into the conversation.

Safety Rules

  1. Always dry run first. For bulk_grade_submissions, set dry_run: true before the real run. Review the output for correctness.
  2. Verify the rubric before grading. Confirm criterion IDs, point ranges, and rating IDs match the assignment rubric. Mismatched IDs cause silent failures or incorrect grades.
  3. Spot-check before bulk. For Strategy B and C, grade 1-2 submissions manually with grade_with_rubric first. Verify in Canvas that the grade and rubric feedback appear correctly.
  4. Respect rate limits. Use max_concurrent: 5 and rate_limit_delay: 1.0 (1 second between batches). Canvas rate limits are approximately 700 requests per 10 minutes.
  5. Do not grade without explicit instructor confirmation. Always present the grading plan (rubric mapping, point values, number of students affected) and wait for approval before submitting grades.

Example Prompts

  • "Grade Assignment 5 using the rubric"
  • "Show me the rubric for the midterm project and grade all submissions"
  • "Bulk grade all ungraded submissions for Assignment 3 -- give full marks on criterion 1 and 80% on criterion 2"
  • "How many submissions still need grading for the final paper?"
  • "Dry run bulk grading for Assignment 7 so I can review before submitting"
  • "Use code execution to grade all 150 homework submissions with custom logic"

Error Recovery

ErrorCauseAction
401 UnauthorizedToken expired or invalidRegenerate Canvas API token
403 ForbiddenNot an instructor/TA for this courseVerify Canvas role
404 Not FoundWrong course, assignment, or rubric IDRe-check IDs with list_assignments or list_all_rubrics
422 UnprocessableInvalid rubric assessment formatVerify criterion IDs and point ranges match the rubric
Partial failures in bulkSome grades submitted, others failedCheck the response for per-student status; retry only failed ones

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Gives 0 of the 12 instructions most education skills give in ~1.6k tokens

Counted across 169 of the 171 authors here whose files we hold, read 2026-08-07

  • Search for existing resources before creating new onesin 7 of 169, across 3 files
  • Check tool responses for errors before proceedingin 7 of 169, across 3 files
  • Reduce request frequency on rate limit errorsin 7 of 169, across 3 files
  • Confirm connection status is ACTIVE before running workflowsin 7 of 169, across 3 files
  • Execute prerequisite steps first in workflowsin 7 of 169, across 3 files
  • Handle pagination by fetching until exhaustedin 7 of 169, across 3 files
  • Re-authenticate if the connection expiredin 6 of 169, across 2 files
  • Always call RUBE_SEARCH_TOOLS first to get schemasin 6 of 169, across 2 files
  • Pass strictly schema-compliant tool argumentsin 6 of 169, across 2 files
  • Run the skill generator if the shared file is missingin 6 of 169, across 3 files
  • Create the coursein 5 of 169, across 3 files
  • List enrolled studentsin 5 of 169, across 3 files

Said here and by no other author read

  • retrieve assignment and rubric details before grading
  • record criterion and rating IDs from the rubric response
  • retrieve all student submissions to determine grading count
  • select a grading strategy based on submission count
  • use single grading for under ten submissions
  • use bulk grading for ten to twenty-nine submissions

Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.