Skip to main content
Glama

get-activity-laps

Retrieve detailed lap data for Strava activities to analyze performance metrics, track progress, and extract raw values for visualization.

Instructions

Retrieves detailed lap data for a specific Strava activity.

Use Cases:

  • Get complete lap data including timestamps, speeds, and metrics

  • Access raw values for detailed analysis or visualization

  • Extract specific lap metrics for comparison or tracking

Parameters:

  • id (required): The unique identifier of the Strava activity.

Output Format: Returns both a human-readable summary and complete JSON data for each lap, including:

  1. A text summary with formatted metrics

  2. Raw lap data containing all fields from the Strava API:

    • Unique lap ID and indices

    • Timestamps (start_date, start_date_local)

    • Distance and timing metrics

    • Speed metrics (average and max)

    • Performance metrics (heart rate, cadence, power if available)

    • Elevation data

    • Resource state information

    • Activity and athlete references

Notes:

  • Requires activity:read scope for public/followers activities, activity:read_all for private activities

  • Returns complete data as received from Strava API without omissions

  • All numeric values are preserved in their original precision

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
idYesThe identifier of the activity to fetch laps for.

Implementation Reference

  • The tool handler for "get-activity-laps" which executes the logic, including fetching data from the Strava client and formatting the response.
    export const getActivityLapsTool = {
        name,
        description,
        inputSchema,
        execute: async ({ id }: GetActivityLapsInput) => {
            const token = process.env.STRAVA_ACCESS_TOKEN;
    
            if (!token) {
                console.error("Missing STRAVA_ACCESS_TOKEN environment variable.");
                return {
                    content: [{ type: "text" as const, text: "Configuration error: Missing Strava access token." }],
                    isError: true
                };
            }
    
            try {
                console.error(`Fetching laps for activity ID: ${id}...`);
                const laps = await getActivityLapsClient(token, id);
    
                if (!laps || laps.length === 0) {
                    return {
                        content: [{ type: "text" as const, text: `✅ No laps found for activity ID: ${id}` }]
                    };
                }
    
                // Generate human-readable summary
                const lapSummaries = laps.map(lap => {
                    const details = [
                        `Lap ${lap.lap_index}: ${lap.name || 'Unnamed Lap'}`,
                        `  Time: ${formatDuration(lap.elapsed_time)} (Moving: ${formatDuration(lap.moving_time)})`,
                        `  Distance: ${(lap.distance / 1000).toFixed(2)} km`,
                        `  Avg Speed: ${lap.average_speed ? (lap.average_speed * 3.6).toFixed(2) + ' km/h' : 'N/A'}`,
                        `  Max Speed: ${lap.max_speed ? (lap.max_speed * 3.6).toFixed(2) + ' km/h' : 'N/A'}`,
                        lap.total_elevation_gain ? `  Elevation Gain: ${lap.total_elevation_gain.toFixed(1)} m` : null,
                        lap.average_heartrate ? `  Avg HR: ${lap.average_heartrate.toFixed(1)} bpm` : null,
                        lap.max_heartrate ? `  Max HR: ${lap.max_heartrate} bpm` : null,
                        lap.average_cadence ? `  Avg Cadence: ${lap.average_cadence.toFixed(1)} rpm` : null,
                        lap.average_watts ? `  Avg Power: ${lap.average_watts.toFixed(1)} W ${lap.device_watts ? '(Sensor)' : ''}` : null,
                    ];
                    return details.filter(d => d !== null).join('\n');
                });
    
                const summaryText = `Activity Laps Summary (ID: ${id}):\n\n${lapSummaries.join('\n\n')}`;
                
                // Add raw data section
                const rawDataText = `\n\nComplete Lap Data:\n${JSON.stringify(laps, null, 2)}`;
                
                console.error(`Successfully fetched ${laps.length} laps for activity ${id}`);
                
                return {
                    content: [
                        { type: "text" as const, text: summaryText },
                        { type: "text" as const, text: rawDataText }
                    ]
                };
            } catch (error) {
                const errorMessage = error instanceof Error ? error.message : String(error);
                console.error(`Error fetching laps for activity ${id}: ${errorMessage}`);
                const userFriendlyMessage = errorMessage.includes("Record Not Found") || errorMessage.includes("404")
                    ? `Activity with ID ${id} not found.`
                    : `An unexpected error occurred while fetching laps for activity ${id}. Details: ${errorMessage}`;
                return {
                    content: [{ type: "text" as const, text: `❌ ${userFriendlyMessage}` }],
                    isError: true
                };
            }
        }
    }; 
  • Input schema for the "get-activity-laps" tool using Zod.
    const inputSchema = z.object({
        id: z.union([z.number(), z.string()]).describe("The identifier of the activity to fetch laps for."),
    });

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/LimeON-source/Strava-MCP'

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