list_activities_tool
Retrieve recent workout sessions from Strava to track athletic performance and training history.
Instructions
List recent activities for the authenticated athlete.
Args: limit: Number of activities to return (default 5)
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No |
Implementation Reference
- server.py:38-51 (handler)Main MCP tool handler for list_activities_tool. Decorated with @mcp.tool() for registration. Validates limit parameter (clamps to MAX_LIMIT=200), gets Strava client, calls list_activities service function, and returns list of dictionaries.
@mcp.tool() def list_activities_tool(limit: int = 5) -> list[dict]: """ List recent activities for the authenticated athlete. Args: limit: Number of activities to return (default 5) """ if limit > MAX_LIMIT: limit = MAX_LIMIT client = get_client() activities = list_activities(client, limit) return [activity.to_dict() for activity in activities] - Service function that fetches activities from Strava API using client.get_activities(). Handles safe extraction of moving_time and creates ActivitySummary dataclass instances with all relevant activity fields.
def list_activities(client: Client, limit: int) -> list[ActivitySummary]: """List recent activities for the authenticated athlete.""" activities = client.get_activities(limit=limit) result = [] for activity in activities: # Handle moving_time safely moving_time = ( getattr(activity.moving_time, "seconds", 0) if activity.moving_time else 0 ) summary = ActivitySummary( id=activity.id or 0, name=activity.name or "", type=str(activity.type), start_date=activity.start_date.isoformat() if activity.start_date else None, distance=float(activity.distance) if activity.distance else 0.0, moving_time=moving_time, total_elevation_gain=float(activity.total_elevation_gain) if activity.total_elevation_gain else 0.0, average_speed=float(activity.average_speed or 0.0), max_speed=float(activity.max_speed or 0.0), ) result.append(summary) return result - strava_mcp/models.py:41-57 (schema)ActivitySummary dataclass schema defining the structure of activity data returned by list_activities_tool. Includes fields like id, name, type, start_date, distance, moving_time, elevation_gain, and speeds. Provides to_dict() method for serialization.
@dataclass class ActivitySummary: """Summary of a Strava activity.""" id: int name: str type: str start_date: Optional[str] distance: float moving_time: int total_elevation_gain: float average_speed: float = 0.0 max_speed: float = 0.0 def to_dict(self) -> dict: """Convert to dictionary for serialization.""" return asdict(self) - server.py:20-24 (helper)MAX_LIMIT constant (200) and FastMCP initialization. The MAX_LIMIT is used by list_activities_tool to clamp the limit parameter and prevent excessive API requests.
# Constants MAX_LIMIT = 200 # Initialize FastMCP mcp = FastMCP("strava-server") - tests/test_limits.py:6-23 (helper)Test verifying that list_activities_tool correctly clamps excessive limit values to MAX_LIMIT. Uses mocking to test the limit validation logic without making actual API calls.
@patch("server.get_client") @patch("server.list_activities") def test_list_activities_tool_limit_clamping(mock_list_activities, mock_get_client): # Setup mock_client = MagicMock() mock_get_client.return_value = mock_client mock_list_activities.return_value = [] # Test with limit > MAX_LIMIT excessive_limit = MAX_LIMIT + 100 list_activities_tool.fn(limit=excessive_limit) # Verify list_activities was called with MAX_LIMIT mock_list_activities.assert_called_once_with(mock_client, MAX_LIMIT) # Verify list_activities was called with MAX_LIMIT mock_list_activities.assert_called_once_with(mock_client, MAX_LIMIT)