Skip to main content
Glama

get_activities

Retrieve and summarize time tracking activities by date, project, and task within a specified date range. Filter results by project ID to focus on specific work data.

Instructions

Get all activities within a date range with automatic summation by date, project, and task. Optionally filter by project ID.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
startDateYesStart date in ISO 8601 format (YYYY-MM-DD)
endDateYesEnd date in ISO 8601 format (YYYY-MM-DD)
projectIdNoOptional project ID to filter activities for a specific project

Implementation Reference

  • The main handler for the get_activities tool. Validates input dates, fetches activities from Moco API, aggregates them by date/project/task, formats the summary, and returns a formatted string response.
    export const getActivitiesTool = { name: 'get_activities', description: 'Get all activities within a date range with automatic summation by date, project, and task. Optionally filter by project ID.', inputSchema: zodToJsonSchema(GetActivitiesSchema), handler: async (params: z.infer<typeof GetActivitiesSchema>): Promise<string> => { const { startDate, endDate, projectId } = params; // Validate date format and range if (!validateDateRange(startDate, endDate)) { return createValidationErrorMessage({ field: 'dateRange', value: `${startDate} to ${endDate}`, reason: 'invalid_date_range' }); } try { const apiService = new MocoApiService(); const activities = await apiService.getActivities(startDate, endDate, projectId); if (activities.length === 0) { return createEmptyResultMessage({ type: 'activities', startDate, endDate, projectId }); } const summary = aggregateActivities(activities, startDate, endDate); return formatActivitiesSummary(summary, projectId); } catch (error) { return `Error retrieving activities: ${error instanceof Error ? error.message : 'Unknown error'}`; } } };
  • Zod schema defining the input parameters for the get_activities tool: required startDate and endDate strings, optional positive projectId number.
    const GetActivitiesSchema = z.object({ startDate: z.string().describe('Start date in ISO 8601 format (YYYY-MM-DD)'), endDate: z.string().describe('End date in ISO 8601 format (YYYY-MM-DD)'), projectId: z.number().positive().optional().describe('Optional project ID to filter activities for a specific project') });
  • src/index.ts:34-42 (registration)
    The getActivitiesTool is imported and included in the AVAILABLE_TOOLS array, which is used by the MCP server to list and dispatch tool calls.
    const AVAILABLE_TOOLS = [ getActivitiesTool, getUserProjectsTool, getUserProjectTasksTool, getUserHolidaysTool, getUserPresencesTool, getUserSickDaysTool, getPublicHolidaysTool ];
  • MocoApiService method that fetches activities from the MoCo API endpoint '/activities' with date range and optional project filter, handling pagination automatically.
    async getActivities(startDate: string, endDate: string, projectId?: number): Promise<Activity[]> { const params: Record<string, string | number> = { from: startDate, to: endDate }; if (projectId) { params.project_id = projectId; } return this.fetchAllPages<Activity>('/activities', params); }
  • Helper function that aggregates raw activities into structured summaries: daily breakdowns, project totals across days, task breakdowns, and grand total.
    function aggregateActivities(activities: Activity[], startDate: string, endDate: string): ActivityRangeSummary { // Group activities by date const activitiesByDate = new Map<string, Activity[]>(); activities.forEach(activity => { if (!activitiesByDate.has(activity.date)) { activitiesByDate.set(activity.date, []); } activitiesByDate.get(activity.date)!.push(activity); }); // Create daily summaries const dailySummaries: DailyActivitySummary[] = []; const projectTotalsMap = new Map<number, { projectName: string; totalHours: number; tasks: Map<number, { taskName: string; totalHours: number }>; }>(); // Sort dates for consistent output const sortedDates = Array.from(activitiesByDate.keys()).sort(); sortedDates.forEach(date => { const dayActivities = activitiesByDate.get(date)!; const dailySummary = createDailySummary(date, dayActivities); dailySummaries.push(dailySummary); // Accumulate project totals across all days dailySummary.projects.forEach(project => { if (!projectTotalsMap.has(project.projectId)) { projectTotalsMap.set(project.projectId, { projectName: project.projectName, totalHours: 0, tasks: new Map() }); } const projectTotal = projectTotalsMap.get(project.projectId)!; projectTotal.totalHours += project.projectTotal.hours; project.tasks.forEach(task => { if (!projectTotal.tasks.has(task.taskId)) { projectTotal.tasks.set(task.taskId, { taskName: task.taskName, totalHours: 0 }); } projectTotal.tasks.get(task.taskId)!.totalHours += task.hours; }); }); }); // Convert project totals map to array format const projectTotals = Array.from(projectTotalsMap.entries()).map(([projectId, data]) => ({ projectId, projectName: data.projectName, total: createTimeFormat(data.totalHours), tasks: Array.from(data.tasks.entries()).map(([taskId, taskData]) => ({ taskId, taskName: taskData.taskName, total: createTimeFormat(taskData.totalHours) })) })); // Calculate grand total const grandTotalHours = sumHours(dailySummaries.map(day => day.dailyTotal.hours)); return { startDate, endDate, dailySummaries, projectTotals, grandTotal: createTimeFormat(grandTotalHours) }; }

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/niondigital/moco-mcp'

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