get_required_courses
Retrieve required courses with progress tracking for N Lobby school portal. Filter by grade, semester, or curriculum category to access detailed course information.
Instructions
Retrieve required courses information with detailed progress tracking
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| grade | No | Filter by grade level (1, 2, or 3) (optional) | |
| semester | No | Filter by term year (e.g., "2024", "2025") (optional) | |
| category | No | Filter by curriculum category (e.g., "国語", "数学", "英語") (optional) |
Implementation Reference
- src/server.ts:629-711 (handler)The primary handler for the 'get_required_courses' MCP tool. Parses input parameters, fetches raw courses data via this.api.getRequiredCourses(), applies filtering logic for grade/semester/category, computes aggregated statistics and groupings using helper methods, and formats a comprehensive summary response as JSON.case "get_required_courses": try { const { grade, semester, category } = args as { grade?: number; semester?: string; category?: string; }; const courses = await this.api.getRequiredCourses(); // Apply filters if provided let filteredCourses = courses; if (grade !== undefined) { // Filter by grade (year) - convert grade number to grade string const gradeString = grade === 1 ? "1年次" : grade === 2 ? "2年次" : grade === 3 ? "3年次" : `${grade}年次`; filteredCourses = filteredCourses.filter( (course) => course.grade === gradeString, ); } if (semester) { // Filter by semester/term - this data isn't directly available in the current structure // Could filter by term year or other available fields filteredCourses = filteredCourses.filter( (course) => course.termYear && course.termYear.toString().includes(semester), ); } if (category) { // Filter by curriculum name (subject category) filteredCourses = filteredCourses.filter( (course) => course.curriculumName && course.curriculumName .toLowerCase() .includes(category.toLowerCase()), ); } // Create a summary with useful information const summary = { totalCourses: filteredCourses.length, filters: { grade, semester, category }, coursesByGrade: this.groupCoursesByGrade(filteredCourses), coursesByCurriculum: this.groupCoursesByCurriculum(filteredCourses), completedCourses: filteredCourses.filter( (course) => course.isCompleted, ).length, inProgressCourses: filteredCourses.filter( (course) => course.isInProgress, ).length, courses: filteredCourses, }; return { content: [ { type: "text", text: JSON.stringify(summary, null, 2), }, ], }; } catch (error) { return { content: [ { type: "text", text: `Error: ${error instanceof Error ? error.message : "Unknown error"}\n\nTo authenticate:\n1. Login to N Lobby in your browser\n2. Open Developer Tools (F12)\n3. Go to Application/Storage tab\n4. Copy cookies and use the set_cookies tool\n5. Use health_check to verify connection`, }, ], }; }
- src/server.ts:222-245 (schema)Input schema definition for the get_required_courses tool, specifying optional filtering parameters: grade (number), semester (string), category (string). Used in tool registration response.{ name: "get_required_courses", description: "Retrieve required courses information with detailed progress tracking", inputSchema: { type: "object", properties: { grade: { type: "number", description: "Filter by grade level (1, 2, or 3) (optional)", }, semester: { type: "string", description: 'Filter by term year (e.g., "2024", "2025") (optional)', }, category: { type: "string", description: 'Filter by curriculum category (e.g., "国語", "数学", "英語") (optional)', }, }, }, },
- src/server.ts:154-450 (registration)Registration of all available tools including 'get_required_courses' via the ListToolsRequestSchema handler. The static tools array defines capabilities and is returned to MCP clients.this.server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ { name: "get_news", description: "Retrieve school news", inputSchema: { type: "object", properties: { category: { type: "string", description: "Filter by category (optional)", }, limit: { type: "number", description: "Maximum number of news items to retrieve (optional, default: 10)", minimum: 1, default: 10, }, sort: { type: "string", description: "Sort order: 'newest' (default), 'oldest', 'title-asc', 'title-desc'", enum: ["newest", "oldest", "title-asc", "title-desc"], }, }, }, }, { name: "get_news_detail", description: "Retrieve detailed information for a specific news article", inputSchema: { type: "object", properties: { newsId: { type: "string", description: "The ID of the news article to retrieve", }, markAsRead: { type: "boolean", description: "Mark the news article as read (optional, default: false)", default: false, }, }, required: ["newsId"], }, }, { name: "get_account_info", description: "Extract account information by parsing Next.js flight data from a rendered page", inputSchema: { type: "object", properties: {}, }, }, { name: "get_student_card_screenshot", description: "Capture a screenshot of the student ID card by following the secure portal redirect flow", inputSchema: { type: "object", properties: {}, }, }, { name: "get_required_courses", description: "Retrieve required courses information with detailed progress tracking", inputSchema: { type: "object", properties: { grade: { type: "number", description: "Filter by grade level (1, 2, or 3) (optional)", }, semester: { type: "string", description: 'Filter by term year (e.g., "2024", "2025") (optional)', }, category: { type: "string", description: 'Filter by curriculum category (e.g., "国語", "数学", "英語") (optional)', }, }, }, }, { name: "get_schedule", description: "Get school schedule for a specific date (backward compatibility)", inputSchema: { type: "object", properties: { date: { type: "string", description: "Date in YYYY-MM-DD format (optional, defaults to today)", }, }, }, }, { name: "get_calendar_events", description: "Get calendar events with advanced options", inputSchema: { type: "object", properties: { calendar_type: { type: "string", enum: ["personal", "school"], description: "Type of calendar to retrieve (personal or school)", default: "personal", }, from_date: { type: "string", description: "Start date in YYYY-MM-DD format (optional). If only from_date is provided, it will be treated as a single day.", }, to_date: { type: "string", description: "End date in YYYY-MM-DD format (optional). Must be at least 1 day after from_date when both are provided.", }, period: { type: "string", enum: ["today", "week", "month"], description: 'Predefined period (optional, overrides from/to dates). Use "today" for single day queries.', }, }, }, }, { name: "test_calendar_endpoints", description: "Test both personal and school calendar endpoints", inputSchema: { type: "object", properties: { from_date: { type: "string", description: "Start date in YYYY-MM-DD format (optional). If only from_date is provided, it will be treated as a single day.", }, to_date: { type: "string", description: "End date in YYYY-MM-DD format (optional). Must be at least 1 day after from_date when both are provided.", }, }, }, }, { name: "set_cookies", description: "Set authentication cookies for N Lobby access", inputSchema: { type: "object", properties: { cookies: { type: "string", description: "Cookie string from authenticated N Lobby session", }, }, required: ["cookies"], }, }, { name: "check_cookies", description: "Check if authentication cookies are set", inputSchema: { type: "object", properties: {}, }, }, { name: "health_check", description: "Check if N Lobby API connection is working", inputSchema: { type: "object", properties: {}, }, }, { name: "debug_connection", description: "Debug N Lobby connection with detailed information", inputSchema: { type: "object", properties: { endpoint: { type: "string", description: "Endpoint to test (default: /news)", default: "/news", }, }, }, }, { name: "test_page_content", description: "Test page content retrieval and show sample content", inputSchema: { type: "object", properties: { endpoint: { type: "string", description: "Endpoint to test (default: /news)", default: "/news", }, length: { type: "number", description: "Number of characters to show (default: 1000)", default: 1000, }, }, }, }, { name: "test_trpc_endpoint", description: "Test specific tRPC endpoint with detailed response", inputSchema: { type: "object", properties: { method: { type: "string", description: "tRPC method to test (e.g., news.getUnreadNewsCount, user.updateLastAccess)", default: "user.updateLastAccess", }, params: { type: "string", description: "JSON string of parameters (optional)", }, }, }, }, { name: "verify_authentication", description: "Verify authentication status and cookie synchronization across all clients", inputSchema: { type: "object", properties: {}, }, }, { name: "interactive_login", description: "Open browser for manual login to N Lobby (no credentials required)", inputSchema: { type: "object", properties: {}, }, }, { name: "login_help", description: "Get help and troubleshooting tips for N Lobby login", inputSchema: { type: "object", properties: { email: { type: "string", description: "Your email address (optional, for personalized help)", }, }, }, }, { name: "mark_news_as_read", description: "Mark news articles as read", inputSchema: { type: "object", properties: { ids: { type: "array", items: { type: "string", }, description: "Array of news article IDs to mark as read", }, }, required: ["ids"], }, }, ], };
- src/server.ts:1234-1254 (helper)Helper utility functions groupCoursesByGrade and groupCoursesByCurriculum used exclusively by the get_required_courses handler to create summary aggregations of filtered courses by grade level and curriculum/subject.private groupCoursesByGrade(courses: Course[]): Record<string, number> { const groups: Record<string, number> = {}; for (const course of courses) { const grade = course.grade || "Unknown"; groups[grade] = (groups[grade] || 0) + 1; } return groups; } private groupCoursesByCurriculum(courses: Course[]): Record<string, number> { const groups: Record<string, number> = {}; for (const course of courses) { const curriculum = course.curriculumName || "Unknown"; groups[curriculum] = (groups[curriculum] || 0) + 1; } return groups; }