Static source inference · medium confidence · detected: Logging
Deprecated protocol patterns detected
Summary
Canvas MCP has 10 tools with basic schemas and descriptions, but significant gaps in quality across naming, descriptions, and error handling. Tool names follow verb_noun convention (good), but descriptions are generic and often lack critical context. Input schemas are present with proper types, but parameter descriptions are minimal. Output schemas are not documented. Error handling is absent. The codebase shows tool definitions exist in extract_tools_test.py (inferred, not directly visible in provided source), which caps tool-level scores. Overall, this is a D-range server with structural basics but insufficient depth for production LLM agent use.
All getter tools claim to return 'all' items without pagination. No limit, offset, or cursor parameters. Large datasets (hundreds of assignments, files) will blow context windows and waste tokens.
Descriptions are uniformly short (33 - 41 chars average) and lack actionable context. Missing WHEN to use, side effects, prerequisites, return format, and constraints. Does not meet 50 - 200 char baseline for LLM-optimized descriptions.
Add pagination to all list/get tools. Minimum: add 'limit' (default 20, max 100) and 'offset' (default 0) params to get_course_assignments, get_course_modules, get_course_announcements, get_course_files, get_course_calendar_events, get_course_list. Return { items: [...], total_count: integer, has_more: boolean }.
Expand all tool descriptions to 50 - 150 chars with WHEN and WHAT details. Example: 'Get upcoming assignment deadlines for the current user. Specify days (1 - 365) to set the look-ahead window; optionally filter by course_id. Useful for planning study schedules or identifying at-risk deadlines. Returns sorted by due_date with submission status.'
Add parameter constraints to descriptions and schemas. Example: days param → 'days (integer, required, range 1 - 365): Number of days to look ahead from today. Default 7.'
Mark sync_canvas_data as destructive in description: 'Synchronize data from Canvas LMS to the local database. **Overwrites existing local data.** If force=true, re-syncs all data even if recently updated; can take minutes for large course rosters. Returns count of courses, assignments, and modules synced. Idempotent if force=false and data unchanged.'
Spec posture evidence
Inferred effective spec: <=2025-11-25.
Relies on Logging (deprecated) - log to stderr or use OpenTelemetry
sync_canvas_data (WRITE risk) description does not declare state mutation. LLMs cannot determine retry safety or side effect severity. No guidance on what happens if sync is interrupted.
Parameter constraints missing across all tools. 'days' param has no documented range (1 - 365?). 'course_id' has no validation (positive integer?). 'query' in search_course_content lacks length/character restrictions. LLMs will pass invalid values; tools must validate and return clear errors.
No error handling guidance anywhere. If sync fails, course not found, or search returns no results, tools provide no recovery suggestions. Agents cannot self-correct or retry intelligently.
Tool definitions inferred from scripts/direct_tools_test.py (not directly visible in provided source). Actual MCP server registration in src/canvas_mcp/server.py not shown. Per HARD SCORING RULES, tools without visible explicit registration are capped at 50 per-tool.
No tool composition or chaining hints. When get_course_assignments returns results, do they include IDs that get_course_modules or search_course_content accept? Unknown. Agents will waste calls on lookup chains.
Add error handling examples to tool descriptions. Example for get_course_list: 'Returns empty list if no courses enrolled. If Canvas API is unreachable, returns error with message: "Canvas API unavailable. Check API_URL and API_KEY configuration."'
Create a discovery/status tool to expose available courses and sync state before agents call getter tools. Helps agents select valid course_id early.
Document which tools accept natural identifiers (course names) vs IDs. If search_course_content accepts 'query', explain fuzzy matching behavior and max result count.
Add idempotent/retry hints to tool descriptions. Example: 'Calling get_course_assignments with the same course_id returns the same result; safe to retry.'
Consider splitting search_course_content if it searches across multiple content types (files, announcements, assignments). Separate tools (search_course_files, search_course_announcements) would let LLMs target specific content types without wasteful broad searches.