Skip to main content
Glama
ai-mcp-garage

MyFitnessPal MCP Server

get_date_range_summary

Analyze nutrition trends and insights from MyFitnessPal data over a specified date range to track dietary patterns and progress.

Instructions

Get aggregate nutrition data over a date range with trends and insights.

Args: start_date: Start date in YYYY-MM-DD format end_date: End date in YYYY-MM-DD format

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
start_dateYes
end_dateYes

Implementation Reference

  • The handler function for the 'get_date_range_summary' tool. It fetches daily nutrition data over a date range using the MyFitnessPal client, computes averages and statistics, and returns a formatted markdown summary including daily averages, tracking stats, and a daily breakdown.
    @mcp.tool
    def get_date_range_summary(start_date: str, end_date: str):
        """
        Get aggregate nutrition data over a date range with trends and insights.
        
        Args:
            start_date: Start date in YYYY-MM-DD format
            end_date: End date in YYYY-MM-DD format
        """
        try:
            start = parse_date(start_date)
            end = parse_date(end_date)
            
            if start > end:
                raise ValueError("Start date must be before or equal to end date")
            
            client = get_client()
            
            # Collect data for each day
            daily_data = []
            
            for day in client.get_date_range(start, end):
                totals = day.totals
                
                daily_data.append({
                    'date': day.date,
                    'calories': totals.get('calories', 0),
                    'carbs': totals.get('carbohydrates', 0),
                    'fat': totals.get('fat', 0),
                    'protein': totals.get('protein', 0),
                    'water_ml': day.water,  # Store as ml
                    'complete': day.complete,
                    'num_meals': len(day.meals),
                    'num_exercises': len(day.exercises)
                })
            
            if not daily_data:
                return text_response("No data available for the specified date range.")
            
            # Calculate aggregates
            num_days = len(daily_data)
            avg_calories = sum(d['calories'] for d in daily_data) / num_days
            avg_carbs = sum(d['carbs'] for d in daily_data) / num_days
            avg_fat = sum(d['fat'] for d in daily_data) / num_days
            avg_protein = sum(d['protein'] for d in daily_data) / num_days
            avg_water_ml = sum(d['water_ml'] for d in daily_data) / num_days
            avg_water_oz = avg_water_ml / 29.5735
            
            complete_days = sum(1 for d in daily_data if d['complete'])
            days_with_exercise = sum(1 for d in daily_data if d['num_exercises'] > 0)
            
            # Format output
            output = f"# Date Range Summary\n"
            output += f"**{start.strftime('%B %d, %Y')}** to **{end.strftime('%B %d, %Y')}**\n"
            output += f"({num_days} days)\n\n"
            
            output += "## Daily Averages\n"
            output += f"- **Calories**: {avg_calories:.0f} kcal/day\n"
            output += f"- **Carbohydrates**: {avg_carbs:.0f}g/day\n"
            output += f"- **Fat**: {avg_fat:.0f}g/day\n"
            output += f"- **Protein**: {avg_protein:.0f}g/day\n"
            output += f"- **Water**: {avg_water_oz:.0f} oz/day ({avg_water_ml:.0f} ml/day)\n\n"
            
            output += "## Tracking Stats\n"
            output += f"- **Days Completed**: {complete_days}/{num_days} ({complete_days/num_days*100:.0f}%)\n"
            output += f"- **Days with Exercise**: {days_with_exercise}/{num_days} ({days_with_exercise/num_days*100:.0f}%)\n\n"
            
            output += "## Daily Breakdown\n"
            for day_data in daily_data:
                d = day_data['date']
                water_oz = day_data['water_ml'] / 29.5735
                output += f"- **{d.strftime('%Y-%m-%d')}**: "
                output += f"{day_data['calories']:.0f} kcal, "
                output += f"{day_data['carbs']:.0f}C/{day_data['fat']:.0f}F/{day_data['protein']:.0f}P, "
                output += f"{water_oz:.0f} oz water"
                
                status = []
                if day_data['complete']:
                    status.append("✓")
                if day_data['num_exercises'] > 0:
                    status.append(f"{day_data['num_exercises']} exercises")
                
                if status:
                    output += f" [{', '.join(status)}]"
                
                output += "\n"
            
            return text_response(output)
            
        except Exception as e:
            return text_response(f"Error retrieving date range summary: {str(e)}")

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observed

TDQS

A3.5/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must carry the full burden. It states the tool aggregates data, implying a read-only operation, but does not explicitly disclose side effects, idempotency, or any constraints. Behavioral traits are insufficiently covered.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is brief and front-loaded with the core purpose, followed by parameter details. Every sentence adds value, though the args list could be integrated into a more structured format.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's purpose (aggregation and trends) and absence of an output schema, the description is vague. It does not specify what metrics, trends, or insights are returned, leaving the agent with an incomplete understanding of the tool's output.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema only provides types and requiredness. The description adds format constraints (YYYY-MM-DD) for both parameters, which is valuable and goes beyond the schema. This compensates for the 0% schema description coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool aggregates nutrition data over a date range, including trends and insights. This specific verb-resource combination distinguishes it from daily siblings like get_daily_summary or get_daily_macros.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies use for date-range queries versus daily tools, but it does not explicitly state when to use or avoid this tool, nor does it mention alternatives. Guidance is only implicit via context with siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.