get_rubric
Retrieve rubric criteria, ratings, and points for a Canvas course using rubric ID or assignment ID.
Instructions
Get detailed rubric criteria, ratings, and points.
Accepts either rubric_id or assignment_id (at least one required).
If both provided, uses rubric_id (more specific).
Args:
course_identifier: Course code or Canvas ID
rubric_id: Canvas rubric ID (direct lookup)
assignment_id: Canvas assignment ID (get rubric attached to assignment)
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| course_identifier | Yes | ||
| rubric_id | No | ||
| assignment_id | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |
Implementation Reference
- src/canvas_mcp/tools/rubrics.py:387-540 (handler)The main handler for the get_rubric tool. It takes course_identifier plus either rubric_id or assignment_id. When rubric_id is provided (Path 1), it fetches rubric details directly from /courses/{id}/rubrics/{rubric_id}. When assignment_id is provided (Path 2), it fetches the assignment with rubric and rubric_settings includes. Returns formatted rubric criteria, ratings, IDs, and points.
async def get_rubric(course_identifier: str | int, rubric_id: str | int | None = None, assignment_id: str | int | None = None) -> str: """Get detailed rubric criteria, ratings, and points. Accepts either rubric_id or assignment_id (at least one required). If both provided, uses rubric_id (more specific). Args: course_identifier: Course code or Canvas ID rubric_id: Canvas rubric ID (direct lookup) assignment_id: Canvas assignment ID (get rubric attached to assignment) """ if rubric_id is None and assignment_id is None: return ( "Error: You must provide either rubric_id or assignment_id.\n\n" "Usage:\n" " - get_rubric(course, rubric_id=123) — look up rubric directly\n" " - get_rubric(course, assignment_id=456) — get rubric attached to an assignment\n" "\nUse list_rubrics to find rubric IDs for a course." ) course_id = await get_course_id(course_identifier) course_display = await get_course_code(course_id) or course_identifier # Path 1: Look up by rubric_id (preferred when both provided) if rubric_id is not None: rubric_id_str = str(rubric_id) response = await make_canvas_request( "get", f"/courses/{course_id}/rubrics/{rubric_id_str}", params={"include[]": ["assessments", "associations"]} ) if "error" in response: return f"Error fetching rubric: {response['error']}" title = response.get("title", "Untitled Rubric") points_possible = response.get("points_possible", 0) reusable = response.get("reusable", False) read_only = response.get("read_only", False) data = response.get("data", []) result = f"Rubric '{title}' in Course {course_display}:\n\n" result += f"Rubric ID: {rubric_id}\n" result += f"Total Points: {points_possible}\n" result += f"Reusable: {'Yes' if reusable else 'No'}\n" result += f"Read Only: {'Yes' if read_only else 'No'}\n" if data: result += f"Number of Criteria: {len(data)}\n\n" result += "Criteria and Ratings:\n" result += "=" * 50 + "\n" for i, criterion in enumerate(data, 1): criterion_id = criterion.get("id", "N/A") description = criterion.get("description", "No description") long_description = criterion.get("long_description", "") points = criterion.get("points", 0) ratings = criterion.get("ratings", []) result += f"\nCriterion #{i}: {description}\n" result += f" ID: {criterion_id}\n" result += f" Points: {points}\n" if long_description and long_description != description: result += f" Description: {truncate_text(long_description, 200)}\n" if ratings: sorted_ratings = sorted(ratings, key=lambda x: x.get("points", 0), reverse=True) for rating in sorted_ratings: rating_desc = rating.get("description", "No description") rating_points = rating.get("points", 0) rating_id = rating.get("id", "N/A") result += f" - {rating_points} pts: {rating_desc} [ID: {rating_id}]\n" rating_long_desc = rating.get("long_description", "") if rating_long_desc and rating_long_desc != rating_desc: result += f" {truncate_text(rating_long_desc, 100)}\n" result += "\n" else: result += "\nNo criteria defined for this rubric.\n" return result # Path 2: Look up via assignment_id assignment_id_str = str(assignment_id) response = await make_canvas_request( "get", f"/courses/{course_id}/assignments/{assignment_id_str}", params={"include[]": ["rubric", "rubric_settings"]} ) if "error" in response: return f"Error fetching rubric: {response['error']}" rubric = response.get("rubric") if not rubric: assignment_name = response.get("name", "Unknown Assignment") return f"No rubric found for assignment '{assignment_name}' in course {course_display}." assignment_name = response.get("name", "Unknown Assignment") rubric_settings = response.get("rubric_settings", {}) use_rubric_for_grading = response.get("use_rubric_for_grading", False) result = f"Rubric for Assignment '{assignment_name}' in Course {course_display}:\n\n" # Grading config (only available via assignment path) result += "Grading Config:\n" result += f" Used for Grading: {'Yes' if use_rubric_for_grading else 'No'}\n" if rubric_settings: result += f" Points Possible: {rubric_settings.get('points_possible', 'N/A')}\n" result += f"Number of Criteria: {len(rubric)}\n\n" # Criteria and ratings result += "Criteria and Ratings:\n" result += "=" * 50 + "\n" total_points = 0 for i, criterion in enumerate(rubric, 1): criterion_id = criterion.get("id", "N/A") description = criterion.get("description", "No description") long_description = criterion.get("long_description", "") points = criterion.get("points", 0) ratings = criterion.get("ratings", []) result += f"\nCriterion #{i}: {description}\n" result += f" ID: {criterion_id}\n" result += f" Points: {points}\n" if long_description and long_description != description: result += f" Description: {truncate_text(long_description, 200)}\n" if ratings: sorted_ratings = sorted(ratings, key=lambda x: x.get("points", 0), reverse=True) for rating in sorted_ratings: rating_desc = rating.get("description", "No description") rating_points = rating.get("points", 0) rating_id = rating.get("id", "N/A") result += f" - {rating_points} pts: {rating_desc} [ID: {rating_id}]\n" rating_long_desc = rating.get("long_description", "") if rating_long_desc and rating_long_desc != rating_desc: result += f" {truncate_text(rating_long_desc, 100)}\n" total_points += points result += "\n" result += f"Total Rubric Points: {total_points}" return result - src/canvas_mcp/tools/rubrics.py:382-383 (registration)The function register_rubric_tools(mcp) is the registration function that wraps @mcp.tool() decorator around get_rubric, registering it as an MCP tool with FastMCP.
def register_rubric_tools(mcp: FastMCP) -> None: """Register all rubric-related MCP tools.""" - src/canvas_mcp/server.py:133-133 (registration)register_rubric_tools(mcp) is called in server.py for educator roles, which causes get_rubric to be registered as an MCP tool.
register_rubric_tools(mcp) - src/canvas_mcp/tools/__init__.py:16-16 (registration)Re-exports register_rubric_tools from the rubrics module through __init__.py for clean imports.
from .rubrics import register_rubric_tools - The register_rubric_tools function acts as both registration and container; the @mcp.tool decorator on line 385 is what actually registers get_rubric with the MCP server.
def register_rubric_tools(mcp: FastMCP) -> None: """Register all rubric-related MCP tools."""