list_modules
Retrieve all modules for a Canvas course, with optional inclusion of module items and filtering by name.
Instructions
List all modules in a course.
Args:
course_identifier: Course code or Canvas ID
include_items: Include summary of items in each module
search_term: Filter modules by name
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| course_identifier | Yes | ||
| include_items | No | ||
| search_term | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |
Implementation Reference
- src/canvas_mcp/tools/modules.py:22-93 (handler)The async function `list_modules` that implements the tool logic. It takes a course_identifier (str or int), optional include_items flag, and optional search_term, fetches modules from the Canvas API, formats them into a human-readable string with details like name, position, state, items count, unlock date, prerequisites, and optionally lists up to 5 items per module.
async def list_modules( course_identifier: str | int, include_items: bool = False, search_term: str | None = None ) -> str: """List all modules in a course. Args: course_identifier: Course code or Canvas ID include_items: Include summary of items in each module search_term: Filter modules by name """ course_id = await get_course_id(course_identifier) params = {"per_page": 100} if include_items: params["include[]"] = ["items"] if search_term: params["search_term"] = search_term modules = await fetch_all_paginated_results( f"/courses/{course_id}/modules", params ) if isinstance(modules, dict) and "error" in modules: return f"Error fetching modules: {modules['error']}" if not modules: return "No modules found in course." course_display = await get_course_code(course_id) or course_identifier result = f"Modules in {course_display}:\n\n" for module in modules: module_id = module.get("id") name = module.get("name", "Unnamed") position = module.get("position", 0) state = module.get("state", "unknown") published = module.get("published", False) items_count = module.get("items_count", 0) unlock_at = module.get("unlock_at") require_sequential = module.get("require_sequential_progress", False) prerequisite_ids = module.get("prerequisite_module_ids", []) result += f"**{name}**\n" result += f" ID: {module_id}\n" result += f" Position: {position}\n" result += f" Status: {state} | Published: {'Yes' if published else 'No'}\n" result += f" Items: {items_count}\n" if unlock_at: result += f" Unlocks: {format_date(unlock_at)}\n" if require_sequential: result += " Sequential Progress: Required\n" if prerequisite_ids: result += f" Prerequisites: {prerequisite_ids}\n" # Include item summary if requested if include_items and "items" in module: items = module.get("items", []) if items: result += " Items:\n" for item in items[:5]: # Show first 5 items item_title = item.get("title", "Untitled") item_type = item.get("type", "Unknown") result += f" - {item_title} ({item_type})\n" if len(items) > 5: result += f" ... and {len(items) - 5} more items\n" result += "\n" return result - src/canvas_mcp/tools/modules.py:17-21 (registration)The `register_shared_module_tools` function that registers the tool via `@mcp.tool` decorator on the `list_modules` function, making it accessible to both students and educators.
def register_shared_module_tools(mcp: FastMCP): """Register module tools accessible to both students and educators.""" @mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) @validate_params - The function signature serves as the schema/type definition: parameters include course_identifier (str|int), include_items (bool, default False), and search_term (str|None). The return type is str.
async def list_modules( course_identifier: str | int, include_items: bool = False, search_term: str | None = None ) -> str: - Imported helper functions used by list_modules: get_course_id (to resolve course identifier), fetch_all_paginated_results (to paginate API calls), get_course_code (for display), format_date (for date formatting), and validate_params (decorator for parameter validation).
from ..core.cache import get_course_code, get_course_id from ..core.client import fetch_all_paginated_results, make_canvas_request from ..core.dates import format_date, parse_date from ..core.validation import validate_params def register_shared_module_tools(mcp: FastMCP): """Register module tools accessible to both students and educators.""" @mcp.tool(annotations=ToolAnnotations(readOnlyHint=True)) @validate_params async def list_modules( course_identifier: str | int, include_items: bool = False, search_term: str | None = None ) -> str: """List all modules in a course. Args: course_identifier: Course code or Canvas ID include_items: Include summary of items in each module search_term: Filter modules by name """ course_id = await get_course_id(course_identifier) params = {"per_page": 100} if include_items: params["include[]"] = ["items"] if search_term: params["search_term"] = search_term modules = await fetch_all_paginated_results( f"/courses/{course_id}/modules", params )