get_activity_timeseries
Retrieve Fitbit activity data like steps, distance, or calories over a specified date range (up to 30 days) in JSON format for analysis or integration.
Instructions
Get the raw JSON response for activity time series data from Fitbit over a date range (max 30 days). Supports various resource paths like 'steps', 'distance', 'calories', 'activityCalories', 'caloriesBMR'.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| resourcePath | Yes | Activity resource to retrieve (e.g., 'steps', 'distance', 'calories') | |
| startDate | Yes | The start date for which to retrieve data (YYYY-MM-DD) | |
| endDate | Yes | The end date for which to retrieve data (YYYY-MM-DD) |
Implementation Reference
- src/activity-timeseries.ts:30-61 (registration)Registers the 'get_activity_timeseries' MCP tool with name, description, parameters schema, and inline handler using the shared registerTool utility.registerTool(server, { name: 'get_activity_timeseries', description: "Get the raw JSON response for activity time series data from Fitbit over a date range (max 30 days). Supports various resource paths like 'steps', 'distance', 'calories', 'activityCalories', 'caloriesBMR'.", parametersSchema: { resourcePath: z .enum([ 'steps', 'distance', 'calories', 'activityCalories', 'caloriesBMR', 'tracker/activityCalories', 'tracker/calories', 'tracker/distance' ]) .describe("Activity resource to retrieve (e.g., 'steps', 'distance', 'calories')"), startDate: CommonSchemas.startDate, endDate: CommonSchemas.endDate, }, handler: async ({ resourcePath, startDate, endDate }: ActivityTimeSeriesParams) => { const endpoint = `activities/${resourcePath}/date/${startDate}/${endDate}.json`; return handleFitbitApiCall<ActivityTimeSeriesResponse, ActivityTimeSeriesParams>( endpoint, { resourcePath, startDate, endDate }, getAccessTokenFn, { errorContext: `resource '${resourcePath}' from ${startDate} to ${endDate}` } ); } });
- src/activity-timeseries.ts:49-60 (handler)The handler function for the tool, which constructs the specific Fitbit API endpoint for activity time series and invokes the shared handleFitbitApiCall helper.handler: async ({ resourcePath, startDate, endDate }: ActivityTimeSeriesParams) => { const endpoint = `activities/${resourcePath}/date/${startDate}/${endDate}.json`; return handleFitbitApiCall<ActivityTimeSeriesResponse, ActivityTimeSeriesParams>( endpoint, { resourcePath, startDate, endDate }, getAccessTokenFn, { errorContext: `resource '${resourcePath}' from ${startDate} to ${endDate}` } ); }
- src/activity-timeseries.ts:33-48 (schema)Zod-based input schema defining parameters for the tool: resourcePath (enum of activity types), startDate, and endDate.parametersSchema: { resourcePath: z .enum([ 'steps', 'distance', 'calories', 'activityCalories', 'caloriesBMR', 'tracker/activityCalories', 'tracker/calories', 'tracker/distance' ]) .describe("Activity resource to retrieve (e.g., 'steps', 'distance', 'calories')"), startDate: CommonSchemas.startDate, endDate: CommonSchemas.endDate, },
- src/index.ts:85-85 (registration)Top-level call to registerActivityTimeSeriesTool on the MCP server instance, integrating the tool into the main application.registerActivityTimeSeriesTool(server, getAccessToken);
- src/utils.ts:183-222 (helper)Shared helper function that executes the Fitbit API request using makeFitbitRequest, handles API errors, empty data checks, and formats the response as MCP tool output.export async function handleFitbitApiCall<TResponse, TParams>( endpoint: string, params: TParams, getAccessTokenFn: () => Promise<string | null>, options: { apiBase?: string; successDataExtractor?: (data: TResponse) => unknown[] | null; noDataMessage?: string; errorContext?: string; } = {} ): Promise<ToolResponseStructure> { const { apiBase = FITBIT_API_VERSIONS.V1, successDataExtractor, noDataMessage, errorContext = JSON.stringify(params) } = options; const responseData = await makeFitbitRequest<TResponse>( endpoint, getAccessTokenFn, apiBase ); if (!responseData) { return createErrorResponse( `${ERROR_MESSAGES.API_REQUEST_FAILED} for ${errorContext}. ${ERROR_MESSAGES.CHECK_TOKEN_PERMISSIONS}.` ); } // Check for empty data if extractor provided if (successDataExtractor) { const extractedData = successDataExtractor(responseData); if (!extractedData || extractedData.length === 0) { return createNoDataResponse(noDataMessage || errorContext); } } return createSuccessResponse(responseData); }