feat: add get_devices, get_gear, and get_user_profile tools
This commit is contained in:
48
server.py
48
server.py
@@ -266,6 +266,54 @@ def get_daily_stats(date: str = "") -> str:
|
||||
return f"Error fetching daily stats: {exc}"
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def get_devices() -> str:
|
||||
"""List paired Garmin devices with model name and firmware version."""
|
||||
if err := _check_auth():
|
||||
return err
|
||||
try:
|
||||
result = _client.get_devices()
|
||||
if not result:
|
||||
return "No devices found."
|
||||
return json.dumps(result, indent=2)
|
||||
except GarminConnectAuthenticationError:
|
||||
return "Authentication error. Call authenticate() again."
|
||||
except Exception as exc:
|
||||
return f"Error fetching devices: {exc}"
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def get_gear() -> str:
|
||||
"""List gear items (shoes, bikes) with mileage and usage stats."""
|
||||
if err := _check_auth():
|
||||
return err
|
||||
try:
|
||||
result = _client.get_gear(_client.display_name)
|
||||
if not result:
|
||||
return "No gear found."
|
||||
return json.dumps(result, indent=2)
|
||||
except GarminConnectAuthenticationError:
|
||||
return "Authentication error. Call authenticate() again."
|
||||
except Exception as exc:
|
||||
return f"Error fetching gear: {exc}"
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def get_user_profile() -> str:
|
||||
"""Get Garmin user profile: display name, age, weight, and HR zones."""
|
||||
if err := _check_auth():
|
||||
return err
|
||||
try:
|
||||
result = _client.get_user_profile()
|
||||
if not result:
|
||||
return "No user profile found."
|
||||
return json.dumps(result, indent=2)
|
||||
except GarminConnectAuthenticationError:
|
||||
return "Authentication error. Call authenticate() again."
|
||||
except Exception as exc:
|
||||
return f"Error fetching user profile: {exc}"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
_startup_login()
|
||||
mcp.run()
|
||||
|
||||
@@ -247,3 +247,52 @@ def test_steps_and_stats_unauthenticated():
|
||||
server._auth_state = "unauthenticated"
|
||||
for fn in (server.get_steps, server.get_daily_stats):
|
||||
assert "Not authenticated" in fn("2026-05-17")
|
||||
|
||||
|
||||
def test_get_devices_success():
|
||||
server._auth_state = "authenticated"
|
||||
server._client = MagicMock()
|
||||
server._client.get_devices.return_value = [
|
||||
{"deviceId": "abc123", "productDisplayName": "Forerunner 965", "softwareVersion": "21.20"}
|
||||
]
|
||||
data = json.loads(server.get_devices())
|
||||
assert data[0]["productDisplayName"] == "Forerunner 965"
|
||||
server._client.get_devices.assert_called_once()
|
||||
|
||||
|
||||
def test_get_devices_empty():
|
||||
server._auth_state = "authenticated"
|
||||
server._client = MagicMock()
|
||||
server._client.get_devices.return_value = []
|
||||
assert server.get_devices() == "No devices found."
|
||||
|
||||
|
||||
def test_get_gear_success():
|
||||
server._auth_state = "authenticated"
|
||||
server._client = MagicMock()
|
||||
server._client.display_name = "john.doe"
|
||||
server._client.get_gear.return_value = [
|
||||
{"gearPk": "shoe1", "customMakeModel": "Nike Pegasus", "totalDistance": 320000.0}
|
||||
]
|
||||
data = json.loads(server.get_gear())
|
||||
assert data[0]["customMakeModel"] == "Nike Pegasus"
|
||||
server._client.get_gear.assert_called_once_with("john.doe")
|
||||
|
||||
|
||||
def test_get_user_profile_success():
|
||||
server._auth_state = "authenticated"
|
||||
server._client = MagicMock()
|
||||
server._client.get_user_profile.return_value = {
|
||||
"displayName": "john.doe",
|
||||
"age": 35,
|
||||
"weight": 75000.0,
|
||||
}
|
||||
data = json.loads(server.get_user_profile())
|
||||
assert data["displayName"] == "john.doe"
|
||||
server._client.get_user_profile.assert_called_once()
|
||||
|
||||
|
||||
def test_gear_devices_profile_unauthenticated():
|
||||
server._auth_state = "unauthenticated"
|
||||
for fn in (server.get_devices, server.get_gear, server.get_user_profile):
|
||||
assert "Not authenticated" in fn()
|
||||
|
||||
Reference in New Issue
Block a user