Skip to main content
Glama
willc121

Garmin Health MCP Server

by willc121

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
NameRequiredDescriptionDefault
start_dateNoStart date (YYYY-MM-DD)
end_dateNoEnd date (YYYY-MM-DD)
activity_typeNoFilter by activity type (e.g., 'running')

Implementation Reference

  • 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, }, }; }
  • 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);
  • 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; }

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/willc121/garmin-mcp-server'

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