get_sleep_data
Retrieve sleep data from your Oura Ring for specified date ranges to analyze sleep patterns, duration, and quality metrics.
Instructions
Get sleep data for a specific date range.
Args:
start_date: Start date in ISO format (YYYY-MM-DD)
end_date: End date in ISO format (YYYY-MM-DD)
Returns:
Dictionary containing sleep data
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| start_date | Yes | ||
| end_date | Yes |
Implementation Reference
- src/oura_mcp_server/server.py:337-358 (handler)MCP tool handler for 'get_sleep_data'. Parses date inputs, checks client initialization, calls OuraClient.get_sleep_data, and handles errors.@mcp.tool() def get_sleep_data(start_date: str, end_date: str) -> dict[str, Any]: """ Get sleep data for a specific date range. Args: start_date: Start date in ISO format (YYYY-MM-DD) end_date: End date in ISO format (YYYY-MM-DD) Returns: Dictionary containing sleep data """ if oura_client is None: return {"error": "Oura client not initialized. Please provide an access token."} try: start = parse_date(start_date) end = parse_date(end_date) return oura_client.get_sleep_data(start, end) except Exception as e: return {"error": str(e)}
- src/oura_mcp_server/server.py:31-122 (helper)OuraClient method implementing the core logic to fetch sleep data from Oura API, transform durations and timestamps, and handle readiness data.def get_sleep_data( self, start_date: date, end_date: Optional[date] = None ) -> dict[str, Any]: """ Get sleep data for a specific date range. Args: start_date: Start date for the query end_date: End date for the query (optional, defaults to start_date) Returns: Dictionary containing sleep data """ if end_date is None: end_date = start_date params = { "start_date": start_date.isoformat(), "end_date": end_date.isoformat(), } url = f"{self.BASE_URL}/sleep" response = self.client.get(url, headers=self.headers, params=params) if response.status_code != 200: error_msg = f"Error {response.status_code}: {response.text}" raise Exception(error_msg) # Get the raw response raw_data = response.json() # Transform the data transformed_data = [] for item in raw_data.get("data", []): # Format time durations awake_time = self._format_duration(item.get("awake_time", 0)) deep_sleep_duration = self._format_duration( item.get("deep_sleep_duration", 0) ) light_sleep_duration = self._format_duration( item.get("light_sleep_duration", 0) ) rem_sleep_duration = self._format_duration( item.get("rem_sleep_duration", 0) ) total_sleep_duration = self._format_duration( item.get("total_sleep_duration", 0) ) time_in_bed = self._format_duration(item.get("time_in_bed", 0)) # Format bedtime timestamps bedtime_start = self._format_time(item.get("bedtime_start", "")) bedtime_end = self._format_time(item.get("bedtime_end", "")) # Extract readiness data if available readiness = item.get("readiness", {}) readiness_score = readiness.get("score") if readiness else None readiness_contributors = ( readiness.get("contributors", {}) if readiness else {} ) # Create transformed item transformed_item = { "day": item.get("day"), "bedtime_start": bedtime_start, "bedtime_end": bedtime_end, "awake_time": awake_time, "deep_sleep_duration": deep_sleep_duration, "light_sleep_duration": light_sleep_duration, "rem_sleep_duration": rem_sleep_duration, "total_sleep_duration": total_sleep_duration, "time_in_bed": time_in_bed, "efficiency": item.get("efficiency"), "latency": item.get("latency"), "restless_periods": item.get("restless_periods"), "average_breath": item.get("average_breath"), "average_heart_rate": item.get("average_heart_rate"), "average_hrv": item.get("average_hrv"), "lowest_heart_rate": item.get("lowest_heart_rate"), } # Add readiness data if available if readiness_score is not None: transformed_item["readiness_score"] = readiness_score transformed_item["readiness_contributors"] = readiness_contributors transformed_data.append(transformed_item) # Return with the original structure but with transformed data return {"data": transformed_data}
- Utility function to parse date strings from tool arguments into date objects, used in the handler.def parse_date(date_str: str) -> date: """ Parse a date string in ISO format (YYYY-MM-DD). Args: date_str: Date string in ISO format Returns: Date object """ try: return date.fromisoformat(date_str) except ValueError as err: raise ValueError( f"Invalid date format: {date_str}. Expected format: YYYY-MM-DD" ) from err
- src/oura_mcp_server/server.py:337-337 (registration)The @mcp.tool() decorator registers the get_sleep_data function as an MCP tool.@mcp.tool()