feat: add health stats tools (sleep, HR, stress, body battery, HRV, SpO2)
This commit is contained in:
102
server.py
102
server.py
@@ -130,6 +130,108 @@ def get_activity_details(activity_id: str) -> str:
|
||||
return f"Error fetching activity details: {exc}"
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def get_sleep(date: str = "") -> str:
|
||||
"""Get sleep data for a date (YYYY-MM-DD): score, stages, duration. Defaults to today."""
|
||||
if err := _check_auth():
|
||||
return err
|
||||
cdate = date or _today()
|
||||
try:
|
||||
result = _client.get_sleep_data(cdate)
|
||||
if not result:
|
||||
return f"No sleep data found for {cdate}"
|
||||
return json.dumps(result, indent=2)
|
||||
except GarminConnectAuthenticationError:
|
||||
return "Authentication error. Call authenticate() again."
|
||||
except Exception as exc:
|
||||
return f"Error fetching sleep data: {exc}"
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def get_heart_rate(date: str = "") -> str:
|
||||
"""Get heart rate data for a date (YYYY-MM-DD): resting HR and daily timeline. Defaults to today."""
|
||||
if err := _check_auth():
|
||||
return err
|
||||
cdate = date or _today()
|
||||
try:
|
||||
result = _client.get_heart_rates(cdate)
|
||||
if not result:
|
||||
return f"No heart rate data found for {cdate}"
|
||||
return json.dumps(result, indent=2)
|
||||
except GarminConnectAuthenticationError:
|
||||
return "Authentication error. Call authenticate() again."
|
||||
except Exception as exc:
|
||||
return f"Error fetching heart rate data: {exc}"
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def get_stress(date: str = "") -> str:
|
||||
"""Get stress level timeline for a date (YYYY-MM-DD). Defaults to today."""
|
||||
if err := _check_auth():
|
||||
return err
|
||||
cdate = date or _today()
|
||||
try:
|
||||
result = _client.get_stress_data(cdate)
|
||||
if not result:
|
||||
return f"No stress data found for {cdate}"
|
||||
return json.dumps(result, indent=2)
|
||||
except GarminConnectAuthenticationError:
|
||||
return "Authentication error. Call authenticate() again."
|
||||
except Exception as exc:
|
||||
return f"Error fetching stress data: {exc}"
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def get_body_battery(date: str = "") -> str:
|
||||
"""Get body battery charge/drain values for a date (YYYY-MM-DD). Defaults to today."""
|
||||
if err := _check_auth():
|
||||
return err
|
||||
cdate = date or _today()
|
||||
try:
|
||||
result = _client.get_body_battery(cdate, cdate)
|
||||
if not result:
|
||||
return f"No body battery data found for {cdate}"
|
||||
return json.dumps(result, indent=2)
|
||||
except GarminConnectAuthenticationError:
|
||||
return "Authentication error. Call authenticate() again."
|
||||
except Exception as exc:
|
||||
return f"Error fetching body battery data: {exc}"
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def get_hrv(date: str = "") -> str:
|
||||
"""Get HRV status and nightly average for a date (YYYY-MM-DD). Defaults to today."""
|
||||
if err := _check_auth():
|
||||
return err
|
||||
cdate = date or _today()
|
||||
try:
|
||||
result = _client.get_hrv_data(cdate)
|
||||
if not result:
|
||||
return f"No HRV data found for {cdate}"
|
||||
return json.dumps(result, indent=2)
|
||||
except GarminConnectAuthenticationError:
|
||||
return "Authentication error. Call authenticate() again."
|
||||
except Exception as exc:
|
||||
return f"Error fetching HRV data: {exc}"
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def get_spo2(date: str = "") -> str:
|
||||
"""Get SpO2 (blood oxygen) readings for a date (YYYY-MM-DD). Defaults to today."""
|
||||
if err := _check_auth():
|
||||
return err
|
||||
cdate = date or _today()
|
||||
try:
|
||||
result = _client.get_spo2_data(cdate)
|
||||
if not result:
|
||||
return f"No SpO2 data found for {cdate}"
|
||||
return json.dumps(result, indent=2)
|
||||
except GarminConnectAuthenticationError:
|
||||
return "Authentication error. Call authenticate() again."
|
||||
except Exception as exc:
|
||||
return f"Error fetching SpO2 data: {exc}"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
_startup_login()
|
||||
mcp.run()
|
||||
|
||||
Reference in New Issue
Block a user