Skip to main content
Glama

get_class_schedule

Retrieve your weekly class schedule from the MUSTer campus system. Filter by specific date or view the full week's timetable with a single request.

Instructions

Get class schedule in this week; pass null for full week, or date (YYYY-MM-DD) to filter. If you need multiple days, pass null once instead of multiple calls.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
dateNoDate filter YYYY-MM-DD; null returns full week

Implementation Reference

  • main.py:190-196 (handler)
    MCP tool handler: thin wrapper that delegates to MUSTerClient.get_class_schedule() and handles errors.
    def tool_get_class_schedule(date: Optional[str] = None) -> Any:
        try:
            schedule_data = muster_client.get_class_schedule(date=date)
            return schedule_data
        except Exception as e:
            return {"error": f"Failed to fetch schedule data: {str(e)}"}
  • Tool schema definition including input schema for optional date parameter.
    Tool(
        name="get_class_schedule",
        description="Get class schedule in this week; pass null for full week, or date (YYYY-MM-DD) to filter. If you need multiple days, pass null once instead of multiple calls.",
        inputSchema={
            "type": "object",
            "properties": {
                "date": {
                    "type": ["string", "null"],
                    "description": "Date filter YYYY-MM-DD; null returns full week",
                }
            },
            "required": [],
        },
    ),
  • main.py:219-220 (registration)
    Tool dispatch registration in the call_tool handler.
    if name == "get_class_schedule":
        return _wrap_json(tool_get_class_schedule(args.get("date")))
  • Core helper method in MUSTerClient: authenticates, downloads Excel schedule via Selenium, parses with pandas, and filters by date if provided.
    def get_class_schedule(self, date: Optional[str] = None) -> Dict[str, Any]:
        """
        Get class schedule data from the MUST schedule website.
        Args:
            date: Optional date in YYYY-MM-DD format to filter results
        """      
        
        self._ensure_driver()
        
        self.heartBeat()
    
        if not self.logged_in:
            if not self.login():
                raise Exception("Login required to get courses.")
        
        # Create temporary download directory for Excel file
        with tempfile.TemporaryDirectory() as download_dir:
            try:
                # Update download preferences for this session
                self.driver.execute_cdp_cmd('Page.setDownloadBehavior', {
                    'behavior': 'allow',
                    'downloadPath': download_dir
                })
                
                # Navigate to schedule page
                self.driver.get(SCHEDULE_URL)
                
                # Login if we're redirected to login page
                current_url = self.driver.current_url.lower()
                if "login" in current_url or "signin" in current_url:
                    try:
                        self.login()
                    except Exception as e:
                        return {"error": f"Failed to login to schedule system: {str(e)}"}
                
                self.heartBeat()
                
                # Export process
                export_btn = WebDriverWait(self.driver, 10).until(
                    EC.element_to_be_clickable(
                        (By.XPATH, "//button[span[text()='導出']]")
                    )
                )
                export_btn.click()
                
                # Expand collapse panel and download
                collapse_header = WebDriverWait(self.driver, 10).until(
                    EC.element_to_be_clickable((By.XPATH, "//div[contains(@class,'ivu-collapse-header') and contains(.,'下載任務')]"))
                )
                collapse_header.click()
                
                download_buttons = WebDriverWait(self.driver, 10).until(
                    EC.presence_of_all_elements_located((By.XPATH, "//button[.//span[contains(text(),'下载') or contains(text(),'下載')]]"))
                )
                
                WebDriverWait(self.driver, 5).until(EC.element_to_be_clickable(download_buttons[-1]))
                download_buttons[-1].click()
                time.sleep(1)
                
                self.heartBeat()
                
                # Cancel any dialogs
                try:
                    cancel_buttons = WebDriverWait(self.driver, 5).until(
                        EC.presence_of_all_elements_located((By.XPATH, "//button[contains(., '取消')]"))
                    )
                    for button in cancel_buttons:
                        try:
                            button.click()
                        except:
                            pass
                except:
                    pass
                
                # Wait for file download
                timeout = 30
                start = time.time()
                
                while True:
                    xlsx_files = glob.glob(os.path.join(download_dir, "*.xlsx"))
                    if xlsx_files:
                        break
                    elif time.time() - start > timeout:
                        return {"error": "Failed to download schedule file within 30 seconds"}
                    else:
                        time.sleep(0.5)
                
                self.heartBeat()
                
                # Process the downloaded file
                xlsx_files = sorted(
                    glob.glob(os.path.join(download_dir, "*.xlsx")),
                    key=os.path.getmtime,
                    reverse=True
                )
                
                latest_xlsx = xlsx_files[0]
                df = pd.read_excel(latest_xlsx)
                schedule_data = df.to_dict('records')
    
                response = {
                    "success": True,
                    "total_classes": len(schedule_data),
                    "schedule": schedule_data
                }
                if date:
                    filtered = [cls for cls in schedule_data if isinstance(cls, dict) and cls.get("日期") == date]
                    response["schedule"] = filtered
                    response["total_classes"] = len(filtered)
                    if not filtered:
                        response["warning"] = "Only current week's schedule is available."
                return response
                
            except Exception as e:
                return {"error": f"Failed to fetch schedule data: {str(e)}"}
            finally:
                self.heartBeat()

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Cosmostima/MUSTer_MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server