toggl_workspace_summary
Retrieve total hours tracked per workspace for a specified date range using Toggl Track integration.
Instructions
Get total hours per workspace 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) |
Implementation Reference
- src/index.ts:661-700 (handler)Main handler for toggl_workspace_summary tool. Fetches time entries for specified or default period, hydrates with cache, groups by workspace, generates summaries using helpers, sorts descending by total hours, and returns structured JSON response.case 'toggl_workspace_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); } const hydrated = await cache.hydrateTimeEntries(entries); const byWorkspace = groupEntriesByWorkspace(hydrated); const summaries: any[] = []; byWorkspace.forEach((wsEntries, wsName) => { const wsId = wsEntries[0]?.workspace_id || 0; summaries.push(generateWorkspaceSummary(wsName, wsId, wsEntries)); }); // Sort by total hours descending summaries.sort((a, b) => b.total_seconds - a.total_seconds); return { content: [{ type: 'text', text: JSON.stringify({ workspace_count: summaries.length, total_hours: secondsToHours(summaries.reduce((t, s) => t + s.total_seconds, 0)), workspaces: summaries }, null, 2) }] }; }
- src/index.ts:291-312 (schema)Schema definition for the tool including name, description, and input parameters (period, start_date, end_date). Used for registration and validation.{ name: 'toggl_workspace_summary', description: 'Get total hours per workspace 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)' } } }, },
- src/utils.ts:198-220 (helper)Helper function that generates a detailed WorkspaceSummary from time entries, computing totals, billable amounts, unique project count, and entry count.export function generateWorkspaceSummary( workspaceName: string, workspaceId: number, entries: HydratedTimeEntry[] ): WorkspaceSummary { const totalSeconds = calculateTotalDuration(entries); const billableSeconds = entries .filter(e => e.billable) .reduce((total, e) => total + (e.duration < 0 ? 0 : e.duration), 0); const projectIds = new Set(entries.map(e => e.project_id).filter(Boolean)); return { workspace_id: workspaceId, workspace_name: workspaceName, total_hours: secondsToHours(totalSeconds), total_seconds: totalSeconds, billable_hours: secondsToHours(billableSeconds), billable_seconds: billableSeconds, project_count: projectIds.size, entry_count: entries.length }; }
- src/utils.ts:127-139 (helper)Utility function to group time entries by workspace name for summary generation.export function groupEntriesByWorkspace(entries: HydratedTimeEntry[]): Map<string, HydratedTimeEntry[]> { const grouped = new Map<string, HydratedTimeEntry[]>(); entries.forEach(entry => { const key = entry.workspace_name; if (!grouped.has(key)) { grouped.set(key, []); } grouped.get(key)!.push(entry); }); return grouped; }
- src/index.ts:386-388 (registration)Registers the listTools handler which exposes all tool schemas including toggl_workspace_summary.server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools }; });