get_glucose_trends
Analyzes glucose data to detect patterns like dawn phenomenon, meal responses, and overnight stability. Identifies recurring issues that may require treatment adjustments.
Instructions
Analyze glucose patterns including dawn phenomenon (early morning rise), meal responses, and overnight stability. Helps identify recurring patterns that may need attention or treatment adjustments.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| period | No | Analysis period for pattern detection. Default: weekly. Use daily for detailed patterns, weekly for typical patterns. |
Implementation Reference
- src/index.ts:127-144 (registration)Tool 'get_glucose_trends' is registered in the tools array with its name, description, and inputSchema. The schema accepts an optional 'period' parameter (enum: daily/weekly/monthly, default: weekly).
{ name: 'get_glucose_trends', description: 'Analyze glucose patterns including dawn phenomenon (early morning rise), meal responses, and overnight stability. Helps identify recurring patterns that may need attention or treatment adjustments.', inputSchema: { type: 'object', properties: { period: { type: 'string', enum: ['daily', 'weekly', 'monthly'], description: 'Analysis period for pattern detection. Default: weekly. Use daily for detailed patterns, weekly for typical patterns.' } }, required: [] }, annotations: { readOnlyHint: true } }, - src/index.ts:325-347 (handler)Handler for 'get_glucose_trends' tool in the CallToolRequestSchema switch. It takes the period argument, fetches glucose history data from the LibreLink client for the relevant number of days, then calls analytics.analyzeTrends() to get the trend analysis.
case 'get_glucose_trends': { if (!client || !analytics) { throw new Error('LibreLinkUp not configured. Use configure_credentials first.'); } const period = (args?.period as 'daily' | 'weekly' | 'monthly') || 'weekly'; const daysToAnalyze = period === 'daily' ? 1 : period === 'weekly' ? 7 : 30; const readings = await client.getGlucoseHistory(daysToAnalyze * 24); const trends = analytics.analyzeTrends(readings, period); return { content: [{ type: 'text', text: JSON.stringify({ period: period, patterns: trends.patterns, dawn_phenomenon: trends.dawnPhenomenon, meal_response_average: trends.mealResponse, overnight_stability: trends.overnightStability }, null, 2) }] }; } - src/glucose-analytics.ts:76-138 (handler)The analyzeTrends() method in GlucoseAnalytics class performs the actual trend analysis. It groups readings by hour, detects dawn phenomenon, calculates overnight stability (stdev), analyzes meal responses (average rise after breakfast/lunch/dinner), checks time-in-range, and measures variability.
analyzeTrends(readings: GlucoseReading[], period: 'daily' | 'weekly' | 'monthly'): GlucoseTrends { const patterns: string[] = []; let dawnPhenomenon = false; let mealResponse = 0; let overnightStability = 0; if (readings.length === 0) { return { patterns, dawnPhenomenon, mealResponse, overnightStability }; } // Group readings by hour of day const byHour = this.groupByHour(readings); // Check for dawn phenomenon (rise between 3am-8am) dawnPhenomenon = this.detectDawnPhenomenon(byHour); if (dawnPhenomenon) { patterns.push('Dawn phenomenon detected - glucose rises in early morning'); } // Calculate overnight stability (10pm-6am) overnightStability = this.calculateOvernightStability(byHour); if (overnightStability < 10) { patterns.push('Excellent overnight glucose stability'); } else if (overnightStability < 20) { patterns.push('Good overnight glucose stability'); } else { patterns.push('Variable overnight glucose - consider reviewing evening routine'); } // Analyze meal responses (approximate based on typical meal times) mealResponse = this.analyzeMealResponse(byHour); if (mealResponse < 30) { patterns.push('Good postprandial glucose control'); } else if (mealResponse < 50) { patterns.push('Moderate postprandial glucose rises'); } else { patterns.push('High postprandial glucose spikes - consider meal composition'); } // Check time in range trend const stats = this.calculateGlucoseStats(readings); if (stats.timeInRange >= 70) { patterns.push(`Excellent time in range: ${stats.timeInRange.toFixed(1)}%`); } else if (stats.timeInRange >= 50) { patterns.push(`Good time in range: ${stats.timeInRange.toFixed(1)}%`); } else { patterns.push(`Time in range needs improvement: ${stats.timeInRange.toFixed(1)}%`); } // Check variability if (stats.coefficientOfVariation < 33) { patterns.push('Low glucose variability - stable control'); } else { patterns.push('High glucose variability - consider consistency improvements'); } return { patterns, dawnPhenomenon, mealResponse: Math.round(mealResponse * 100) / 100, overnightStability: Math.round(overnightStability * 100) / 100 }; } - src/glucose-analytics.ts:143-158 (helper)Helper method groupByHour() that groups glucose readings by the hour of day (0-23) for pattern analysis.
private groupByHour(readings: GlucoseReading[]): Map<number, number[]> { const byHour = new Map<number, number[]>(); for (let i = 0; i < 24; i++) { byHour.set(i, []); } for (const reading of readings) { const hour = new Date(reading.timestamp).getHours(); const values = byHour.get(hour) || []; values.push(reading.value); byHour.set(hour, values); } return byHour; } - src/types.ts:45-50 (schema)The GlucoseTrends interface defines the return type for analyzeTrends() with fields: patterns (string array), dawnPhenomenon (boolean), mealResponse (number), overnightStability (number).
export interface GlucoseTrends { patterns: string[]; dawnPhenomenon: boolean; mealResponse: number; overnightStability: number; }