mcmillan_heart_rate_zones
Calculate personalized heart rate training zones using McMillan methodology. Input age and resting heart rate to determine optimal intensity levels for running workouts.
Instructions
Calculate heart rate training zones based on age, resting heart rate, and optional max heart rate. Uses McMillan methodology with multiple max HR estimation formulas and both HRMAX and HRRESERVE methods.
Args: age: Runner's age in years resting_heart_rate: Resting heart rate in BPM max_heart_rate: Optional maximum heart rate in BPM (if None, will be estimated)
Returns: Dictionary containing estimated max HR, effective max HR, and training zones with both HRMAX and HRRESERVE calculations
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| age | Yes | ||
| resting_heart_rate | Yes | ||
| max_heart_rate | No |
Implementation Reference
- The MCP tool handler and registration for 'mcmillan_heart_rate_zones'. This function wraps the core heart_rate_zones helper, provides error handling, and is registered via @mcp.tool decorator.@mcp.tool def mcmillan_heart_rate_zones(age: int, resting_heart_rate: int, max_heart_rate: int = None) -> dict: """ Calculate heart rate training zones based on age, resting heart rate, and optional max heart rate. Uses McMillan methodology with multiple max HR estimation formulas and both HRMAX and HRRESERVE methods. Args: age: Runner's age in years resting_heart_rate: Resting heart rate in BPM max_heart_rate: Optional maximum heart rate in BPM (if None, will be estimated) Returns: Dictionary containing estimated max HR, effective max HR, and training zones with both HRMAX and HRRESERVE calculations """ try: return heart_rate_zones(age, resting_heart_rate, max_heart_rate) except Exception as e: return {"error": str(e)}
- Core helper function implementing the McMillan heart rate zones calculation logic, including input validation, max HR estimation using averaged formulas, and computation of training zones using both HRMAX (%) and HRRESERVE (Karvonen) methods.def heart_rate_zones(age: int, resting_heart_rate: int, max_heart_rate: int = None) -> dict: """ Calculate heart rate zones based on age, resting heart rate, and optional max heart rate. Uses multiple formulas to estimate max heart rate if not provided, then calculates training zones using both HRMAX and HRRESERVE methods. Args: age: Runner's age in years resting_heart_rate: Resting heart rate in BPM max_heart_rate: Optional maximum heart rate in BPM (if None, will be estimated) Returns: dict: Dictionary containing estimated max HR and training zones Raises: InvalidInputError: If age, resting_heart_rate, or max_heart_rate are not positive """ # Input validation if age <= 0: raise InvalidInputError("Age must be positive") if resting_heart_rate <= 0: raise InvalidInputError("Resting heart rate must be positive") if max_heart_rate is not None and max_heart_rate <= 0: raise InvalidInputError("Max heart rate must be positive") # Calculate estimated max heart rate using multiple formulas formula_results = [formula(age) for formula in MAX_HR_FORMULAS.values()] estimated_max_hr = round(sum(formula_results) / len(formula_results)) # Use provided max heart rate if available, otherwise use estimated effective_max_hr = max_heart_rate if max_heart_rate is not None else estimated_max_hr # Use predefined training zone definitions zone_definitions = HR_ZONE_DEFINITIONS # Calculate heart rate zones result = { "estimated_max_heart_rate": estimated_max_hr, "effective_max_heart_rate": effective_max_hr, "resting_heart_rate": resting_heart_rate, "zones": {} } for zone_group, zones in zone_definitions.items(): result["zones"][zone_group] = { "description": f"{zone_group.title()} Zone training", "types": {} } for zone_name, zone_data in zones.items(): hrmax_min, hrmax_max = zone_data["hrmax"] hrreserve_min, hrreserve_max = zone_data["hrreserve"] # Calculate HRMAX method (percentage of max heart rate) hrmax_min_bpm = round((hrmax_min / 100) * effective_max_hr) hrmax_max_bpm = round((hrmax_max / 100) * effective_max_hr) # Calculate HRRESERVE method (percentage of heart rate reserve + resting) hr_reserve = effective_max_hr - resting_heart_rate hrreserve_min_bpm = round((hrreserve_min / 100) * hr_reserve + resting_heart_rate) hrreserve_max_bpm = round((hrreserve_max / 100) * hr_reserve + resting_heart_rate) result["zones"][zone_group]["types"][zone_name] = { "description": zone_data["description"], "hrmax": { "min": hrmax_min_bpm, "max": hrmax_max_bpm, "range": f"{hrmax_min_bpm}-{hrmax_max_bpm} BPM" }, "hrreserve": { "min": hrreserve_min_bpm, "max": hrreserve_max_bpm, "range": f"{hrreserve_min_bpm}-{hrreserve_max_bpm} BPM" } } return result