get_courses
Retrieve enrolled courses from the eClass platform to access academic information and manage coursework.
Instructions
Get list of enrolled courses from eClass
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| random_string | Yes | Dummy parameter for no-parameter tools |
Implementation Reference
- src/eclass_mcp_server/server.py:112-125 (registration)Registration of the 'get_courses' tool in the MCP server's list_tools handler, including schema definition.types.Tool( name="get_courses", description="Get list of enrolled courses from eClass", inputSchema={ "type": "object", "properties": { "random_string": { "type": "string", "description": "Dummy parameter for no-parameter tools" }, }, "required": ["random_string"], }, ),
- src/eclass_mcp_server/server.py:202-206 (handler)Primary MCP tool handler for 'get_courses', which invokes the course management logic and formats the response.async def handle_get_courses() -> List[types.TextContent]: """Handle getting the list of enrolled courses.""" success, message, courses = course_management.get_courses(session_state) return [course_management.format_courses_response(success, message, courses)]
- Core implementation of get_courses: authenticates session, fetches portfolio page, extracts courses using HTML parsing, handles errors.def get_courses( session_state: SessionState ) -> Tuple[bool, Optional[str], Optional[List[Dict[str, str]]]]: """ Retrieve a list of enrolled courses from eClass. Returns: Tuple of (success, message, courses). On success: (True, None, courses_list) On empty result: (True, message, []) On failure: (False, error_message, None) """ if not session_state.logged_in: return False, "Not logged in. Please log in first using the login tool.", None if not session_state.is_session_valid(): return False, "Session expired. Please log in again.", None try: response = session_state.session.get(session_state.portfolio_url) response.raise_for_status() courses = html_parsing.extract_courses(response.text, session_state.base_url) session_state.courses = courses if not courses: return True, "No courses found. You may not be enrolled in any courses.", [] logger.info(f"Successfully retrieved {len(courses)} courses") return True, None, courses except requests.RequestException as e: logger.error(f"Network error getting courses: {e}") return False, f"Network error retrieving courses: {e}", None except Exception as e: logger.error(f"Error getting courses: {e}") return False, f"Error retrieving courses: {e}", None
- Helper function to format the response TextContent for the get_courses tool.def format_courses_response( success: bool, message: Optional[str], courses: Optional[List[Dict[str, str]]] ) -> types.TextContent: """Format course list response for MCP.""" if not success: return types.TextContent( type="text", text=f"Error: {message}", ) if message: # No courses found message return types.TextContent( type="text", text=message, ) course_list = html_parsing.format_course_list(courses) return types.TextContent( type="text", text=f"Found {len(courses)} courses:\n\n{course_list}", )
- Helper function that parses the HTML of the portfolio page to extract course names and URLs using BeautifulSoup.def extract_courses(html_content: str, base_url: str) -> List[Dict[str, str]]: """ Extract course information from the portfolio page. Returns: List of dicts with 'name' and 'url' keys. """ courses = [] soup = BeautifulSoup(html_content, 'html.parser') # Try specific course selectors course_elements = ( soup.select('.course-title') or soup.select('.lesson-title') or soup.select('.course-box .title') or soup.select('.course-info h4') ) if course_elements: for course_elem in course_elements: course_link = course_elem.find('a') or course_elem if course_link and course_link.get('href'): course_name = course_link.text.strip() course_url = course_link.get('href') if course_name: courses.append({ 'name': course_name, 'url': _make_absolute_url(course_url, base_url) }) else: # Fallback: find course links by URL pattern for link in soup.find_all('a'): href = link.get('href', '') if 'courses' in href or 'course.php' in href: course_name = link.text.strip() if course_name: courses.append({ 'name': course_name, 'url': _make_absolute_url(href, base_url) }) logger.debug(f"Extracted {len(courses)} courses") return courses