toggl_project_summary
Generate project time summaries from Toggl Track data. Calculate total hours per project for specified date ranges to analyze time allocation and track project progress.
Instructions
Get total hours per project for a date range
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| period | No | Predefined period | |
| start_date | No | Start date (YYYY-MM-DD format) | |
| end_date | No | End date (YYYY-MM-DD format) | |
| workspace_id | No | Filter by workspace ID |
Implementation Reference
- src/index.ts:617-659 (handler)Main handler logic for the 'toggl_project_summary' tool. Fetches time entries based on input parameters, hydrates them using cache, groups by project using helper, generates summaries, sorts by total hours descending, and returns formatted JSON response.case 'toggl_project_summary': { await ensureCache(); let entries: TimeEntry[]; if (args?.period) { const range = getDateRange(args.period as any); entries = await api.getTimeEntriesForDateRange(range.start, range.end); } else if (args?.start_date && args?.end_date) { const start = new Date(args.start_date as string); const end = new Date(args.end_date as string); entries = await api.getTimeEntriesForDateRange(start, end); } else { // Default to current week entries = await api.getTimeEntriesForWeek(0); } if (args?.workspace_id) { entries = entries.filter(e => e.workspace_id === args.workspace_id); } const hydrated = await cache.hydrateTimeEntries(entries); const byProject = groupEntriesByProject(hydrated); const summaries: any[] = []; byProject.forEach((projectEntries, projectName) => { summaries.push(generateProjectSummary(projectName, projectEntries)); }); // Sort by total hours descending summaries.sort((a, b) => b.total_seconds - a.total_seconds); return { content: [{ type: 'text', text: JSON.stringify({ project_count: summaries.length, total_hours: secondsToHours(summaries.reduce((t, s) => t + s.total_seconds, 0)), projects: summaries }, null, 2) }] }; }
- src/index.ts:265-290 (schema)Tool schema definition including name, description, and input schema for parameters like period, start_date, end_date, and workspace_id.{ name: 'toggl_project_summary', description: 'Get total hours per project for a date range', inputSchema: { type: 'object', properties: { period: { type: 'string', enum: ['week', 'lastWeek', 'month', 'lastMonth'], description: 'Predefined period' }, start_date: { type: 'string', description: 'Start date (YYYY-MM-DD format)' }, end_date: { type: 'string', description: 'End date (YYYY-MM-DD format)' }, workspace_id: { type: 'number', description: 'Filter by workspace ID' } } }, },
- src/utils.ts:111-124 (helper)Helper function to group hydrated time entries by project name, used in project summary generation.// Group time entries by project export function groupEntriesByProject(entries: HydratedTimeEntry[]): Map<string, HydratedTimeEntry[]> { const grouped = new Map<string, HydratedTimeEntry[]>(); entries.forEach(entry => { const key = entry.project_name || 'No Project'; if (!grouped.has(key)) { grouped.set(key, []); } grouped.get(key)!.push(entry); }); return grouped; }
- src/utils.ts:174-195 (helper)Core helper function that generates a ProjectSummary object from project name and entries, calculating total and billable hours.// Generate project summary export function generateProjectSummary( projectName: string, entries: HydratedTimeEntry[] ): ProjectSummary { const totalSeconds = calculateTotalDuration(entries); const billableSeconds = entries .filter(e => e.billable) .reduce((total, e) => total + (e.duration < 0 ? 0 : e.duration), 0); return { project_id: entries[0]?.project_id, project_name: projectName, client_name: entries[0]?.client_name, workspace_name: entries[0]?.workspace_name || 'Unknown', total_hours: secondsToHours(totalSeconds), total_seconds: totalSeconds, billable_hours: secondsToHours(billableSeconds), billable_seconds: billableSeconds, entry_count: entries.length }; }
- src/utils.ts:11-14 (helper)Utility function to convert total seconds to decimal hours, used in summaries.// Convert seconds to hours with decimal precision export function secondsToHours(seconds: number): number { return Math.round((seconds / 3600) * 100) / 100; }