CRITICAL: No input parameter schemas visible in source code. All 50 tools lack JSON Schema definitions with type, properties, required, and description fields. This blocks proper tool registration and LLM parameter validation.
Add complete input parameter schemas (JSON Schema) to all 50 tools. For each parameter, include: type (string|number|boolean|array|object), description (30-100 chars), required boolean, constraints (enum, min, max, pattern, minLength, maxLength).
Expand tool descriptions from current 28-48 chars to 80-150 chars. Each description must answer: WHAT does it do? WHEN should an LLM call it instead of a similar tool? WHAT structure does it return? Example for get_current_courses: 'Returns the courses you are actively enrolled in this semester, including course ID, name, term, and enrollment status. Call this first to discover available courses before fetching assignments or grades.'
Document parameter constraints inline. Examples: 'course_id (string, required): The Canvas course ID. Pass the ID returned by get_current_courses.', 'limit (integer, 1-100, default 20): Maximum results per page.' Avoid example values (e.g., 'e.g., 12345'); use formal constraints instead.
Add documented output schemas to every tool response. Specify return type (object|array) and key fields with types. Example for get_current_courses: 'Returns array of objects: [{id: number, name: string, code: string, term: string, enrollment_state: string}]'.
Clarify overlapping tools. Rename or better document: (a) get_current_courses vs get_courses, are these active vs all-time enrollments? (b) read_file vs read_file_by_id, when to use each? (c) get_assignment_details vs get_detailed_submission, what's different?
Add pagination guidance to discovery/list tools (list_modules, list_quizzes, get_files, list_group_members, list_group_discussions). Document: max default result count (recommend 20-50), support for limit/offset/cursor parameters, and whether a total count or next_cursor is returned.
CRITICAL: Tool descriptions are uniformly generic (28-48 chars) and lack actionable context. Examples: 'Get the user's currently active courses' (44 chars), 'List all courses available to the user' (39 chars). Descriptions do not answer: WHEN to use this vs similar tools? What structure is returned? Prerequisites? How to chain with other tools? Violates 50-200 char optimized range baseline.
CRITICAL: No parameter-level descriptions anywhere in source. Tools that accept parameters (e.g., course_id, assignment_id, query string) have no documented constraints, formats, enums, or type information. An LLM cannot determine if 'find_files' expects a course_id (required), filename pattern (optional), or both.
No documented output schemas. LLMs cannot infer what fields are returned by get_current_courses, get_assignments, get_grades, or other tools. This breaks tool chaining, if get_courses returns course_id but a downstream tool expects course_code, the agent has no way to know.
Write operations (post_discussion_reply, reply_to_discussion_entry, send_message, reply_to_conversation, post_group_discussion) lack error handling guidance. No documented recovery paths, retryability classification, or idempotency guarantees. An agent calling send_message twice should know if it creates a duplicate or safely re-sends.
No pagination guidance. Tools like get_discussions, list_quizzes, get_files should document max result count and pagination support (page, limit, cursor parameters). Without this, large result sets could exceed context limits or timeout.
No distinction between get_current_courses and get_courses. Both are READ_ONLY tools with identical-sounding names, but descriptions don't clarify: is get_current_courses the actively enrolled courses this semester? Is get_courses historical or all available? LLMs will conflate them and may pick the wrong one.
Overlapping tools for similar operations lack clear delineation. Examples: read_file vs read_file_by_id (what parameter names do they use? Under what conditions should LLM choose each?), get_assignment_details vs get_detailed_submission (what's the difference?). Descriptions do not explain when to use each.
Tools accept natural identifiers (course names, user emails, file paths) per description hints, but no parameter schema documents this. If find_files accepts a query string and a course_id, neither type nor range is specified. LLMs cannot validate before calling.
For write operations (post_discussion_reply, send_message, post_group_discussion), document idempotency and error recovery. Example: 'Idempotent: calling twice with same content returns same message ID. Retryable on network errors; returns 409 Conflict if message already posted.'
Add parameter descriptions distinguishing between human-readable identifiers and system IDs. If find_files accepts both a filename pattern and course_id, document: 'course_id (string, optional): Pass the ID from get_current_courses. If omitted, searches all enrolled courses.' and 'filename (string, optional): Partial filename pattern (case-insensitive, e.g., "syllabus" matches "Syllabus_2024.pdf").'
Document tool chaining paths. If users typically call get_current_courses → get_assignments → get_assignment_details, add a note in get_current_courses description: 'To work with assignments, pass the course_id to get_assignments().'
Add error handling guidance to tools accepting search/filter parameters. Example for find_files: 'If no files match the query, returns empty array. Ensure filename pattern uses common keywords (e.g., "lecture", "project", "reading") to improve match likelihood. Call get_files() to browse all course files if search yields nothing.'
Remove generic tool names like smart_search or provide explicit description of what LLM reasoning strategy triggers it. Current description 'Intelligently search course content using AI-powered discovery' is vague, does this use vector embeddings, keyword matching, or something else? When should an LLM prefer this over find_files or read_page?
Validate all parameters server-side and return actionable errors. Instead of a bare 404, return: 'Course ID 12345 not found. Available courses: [course_id: 101, name: "Biology 101"], [course_id: 102, name: "Chemistry 102"]. Call get_current_courses() to list all enrolled courses.' This enables LLM self-correction without extra discovery calls.