get_activities
Retrieve activity breakdowns from Garmin health data, including counts, distances, and durations by activity type within specified date ranges.
Instructions
Get activity breakdown by type, including counts, distances, and durations
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| start_date | No | Start date (YYYY-MM-DD) | |
| end_date | No | End date (YYYY-MM-DD) | |
| activity_type | No | Filter by activity type (e.g., 'running') |
Implementation Reference
- src/index.ts:99-142 (handler)The core handler function for the 'get_activities' tool. Fetches all activities using fetchAllActivities helper, applies optional filters for date range and activity type, aggregates statistics by activity type (count, total km, total hours), sorts by count descending, and returns total activities, breakdown, and date range.async function getActivities( startDate?: string, endDate?: string, activityType?: string ) { const all = await fetchAllActivities(); let filtered = all; if (startDate) filtered = filtered.filter((a) => a.start_time >= startDate); if (endDate) filtered = filtered.filter((a) => a.start_time <= endDate); if (activityType) filtered = filtered.filter((a) => a.activity_type === activityType); const groups: Record< string, { count: number; totalKm: number; totalHours: number } > = {}; filtered.forEach((a) => { const type = a.activity_type || "unknown"; if (!groups[type]) groups[type] = { count: 0, totalKm: 0, totalHours: 0 }; groups[type].count += 1; groups[type].totalKm += a.distance_km || 0; groups[type].totalHours += (a.duration_minutes || 0) / 60; }); const breakdown = Object.entries(groups) .map(([type, d]) => ({ activity_type: type, count: d.count, total_km: Math.round(d.totalKm * 10) / 10, total_hours: Math.round(d.totalHours * 10) / 10, })) .sort((a, b) => b.count - a.count); return { total_activities: filtered.length, breakdown, date_range: { start: filtered[0]?.start_time?.split("T")[0] || null, end: filtered[filtered.length - 1]?.start_time?.split("T")[0] || null, }, }; }
- src/index.ts:340-355 (schema)The tool schema definition in the ListTools response, specifying the name, description, and inputSchema with optional parameters: start_date, end_date, activity_type.{ name: "get_activities", description: "Get activity breakdown by type, including counts, distances, and durations", inputSchema: { type: "object", properties: { start_date: { type: "string", description: "Start date (YYYY-MM-DD)" }, end_date: { type: "string", description: "End date (YYYY-MM-DD)" }, activity_type: { type: "string", description: "Filter by activity type (e.g., 'running')", }, }, }, },
- src/index.ts:411-412 (registration)Registration in the CallToolRequestHandler switch statement: maps the 'get_activities' tool name to a call of the getActivities handler with parsed arguments.case "get_activities": result = await getActivities(a.start_date, a.end_date, a.activity_type);
- src/index.ts:41-62 (helper)Helper function used by getActivities to paginate and fetch all activities data from the Supabase 'activities' table.async function fetchAllActivities() { const pageSize = 1000; let from = 0; const all: any[] = []; while (true) { const { data, error } = await supabase .from("activities") .select("activity_type, distance_km, duration_minutes, avg_hr, start_time") .order("start_time", { ascending: true }) .range(from, from + pageSize - 1); if (error) throw error; if (!data || data.length === 0) break; all.push(...data); if (data.length < pageSize) break; from += pageSize; } return all; }