@goodsamsoftware/freshbooks-mcp 1.0.6 → 1.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +357 -357
  3. package/dist/tools/client/client-create.js +38 -38
  4. package/dist/tools/client/client-list.js +47 -47
  5. package/dist/tools/client/client-update.js +34 -34
  6. package/dist/tools/credit-note/creditnote-single.js +18 -18
  7. package/dist/tools/expense/expense-update.d.ts.map +1 -1
  8. package/dist/tools/expense/expense-update.js +4 -4
  9. package/dist/tools/expense/expense-update.js.map +1 -1
  10. package/dist/tools/invoice/invoice-list.js +40 -40
  11. package/dist/tools/project/project-create.js +34 -34
  12. package/dist/tools/project/project-delete.js +38 -38
  13. package/dist/tools/project/project-list.js +38 -38
  14. package/dist/tools/project/project-single.js +23 -23
  15. package/dist/tools/project/project-update.js +37 -37
  16. package/dist/tools/task/task-create.js +36 -36
  17. package/dist/tools/task/task-delete.js +35 -35
  18. package/dist/tools/task/task-list.js +28 -28
  19. package/dist/tools/task/task-single.js +25 -25
  20. package/dist/tools/task/task-update.js +39 -39
  21. package/dist/tools/time-entry/timeentry-create.js +49 -49
  22. package/dist/tools/time-entry/timeentry-delete.js +48 -48
  23. package/dist/tools/time-entry/timeentry-list.js +53 -53
  24. package/dist/tools/time-entry/timeentry-single.js +28 -28
  25. package/dist/tools/time-entry/timeentry-update.js +61 -61
  26. package/dist/tools/timer/timer-current.js +54 -54
  27. package/dist/tools/timer/timer-discard.js +41 -41
  28. package/dist/tools/timer/timer-start.js +43 -43
  29. package/dist/tools/timer/timer-stop.js +33 -33
  30. package/package.json +88 -88
@@ -11,55 +11,55 @@ import { logger } from '../../utils/logger.js';
11
11
  */
12
12
  export const timeentryCreateTool = {
13
13
  name: 'timeentry_create',
14
- description: `Create a new time entry in FreshBooks.
15
-
16
- WHEN TO USE:
17
- - User says "log my time", "track time", "record hours", "add time entry"
18
- - User mentions working on a project with duration
19
- - User wants to record billable or non-billable time
20
- - User asks "log 2 hours on project X", "track 45 minutes of work"
21
-
22
- REQUIRED:
23
- - businessId: FreshBooks business ID (get from user_me -> businessMemberships[].business.id)
24
- - duration: Time in seconds (or ask user for hours/minutes and convert)
25
- * 1 hour = 3600 seconds
26
- * 1 minute = 60 seconds
27
- * Example: 2 hours 30 minutes = 9000 seconds
28
-
29
- OPTIONAL BUT RECOMMENDED:
30
- - note: Description of work performed (improves billing accuracy)
31
- - projectId: Associate with a project
32
- - clientId: Associate with a client
33
- - serviceId: Service type for billing categorization
34
- - taskId: Associate with a task
35
- - billable: Whether time is billable (default: true if isLogged=true)
36
- - startedAt: When work began (ISO 8601 format, defaults to now)
37
- - isLogged: Whether time is logged (default: true)
38
- * Set to false for active timers (with duration=0 and active=true)
39
-
40
- SPECIAL CASES:
41
- - To start a timer: Set duration=0, active=true, isLogged=false
42
- - For completed work: Set duration to actual seconds, isLogged=true
43
-
44
- RETURNS:
45
- Created time entry with:
46
- - id: New time entry ID (save this for updates/deletes)
47
- - duration: Confirmed duration in seconds
48
- - All other time entry fields
49
-
50
- EXAMPLES:
51
- User says: "Log 2 hours on Project Alpha for code review"
52
- → duration: 7200 (2 * 3600)
53
- → note: "code review"
54
- → projectId: (look up Project Alpha)
55
-
56
- User says: "Track 45 minutes of meeting time"
57
- → duration: 2700 (45 * 60)
58
- → note: "meeting"
59
-
60
- User says: "Record 3 hours of development work for client ABC"
61
- → duration: 10800 (3 * 3600)
62
- → note: "development work"
14
+ description: `Create a new time entry in FreshBooks.
15
+
16
+ WHEN TO USE:
17
+ - User says "log my time", "track time", "record hours", "add time entry"
18
+ - User mentions working on a project with duration
19
+ - User wants to record billable or non-billable time
20
+ - User asks "log 2 hours on project X", "track 45 minutes of work"
21
+
22
+ REQUIRED:
23
+ - businessId: FreshBooks business ID (get from user_me -> businessMemberships[].business.id)
24
+ - duration: Time in seconds (or ask user for hours/minutes and convert)
25
+ * 1 hour = 3600 seconds
26
+ * 1 minute = 60 seconds
27
+ * Example: 2 hours 30 minutes = 9000 seconds
28
+
29
+ OPTIONAL BUT RECOMMENDED:
30
+ - note: Description of work performed (improves billing accuracy)
31
+ - projectId: Associate with a project
32
+ - clientId: Associate with a client
33
+ - serviceId: Service type for billing categorization
34
+ - taskId: Associate with a task
35
+ - billable: Whether time is billable (default: true if isLogged=true)
36
+ - startedAt: When work began (ISO 8601 format, defaults to now)
37
+ - isLogged: Whether time is logged (default: true)
38
+ * Set to false for active timers (with duration=0 and active=true)
39
+
40
+ SPECIAL CASES:
41
+ - To start a timer: Set duration=0, active=true, isLogged=false
42
+ - For completed work: Set duration to actual seconds, isLogged=true
43
+
44
+ RETURNS:
45
+ Created time entry with:
46
+ - id: New time entry ID (save this for updates/deletes)
47
+ - duration: Confirmed duration in seconds
48
+ - All other time entry fields
49
+
50
+ EXAMPLES:
51
+ User says: "Log 2 hours on Project Alpha for code review"
52
+ → duration: 7200 (2 * 3600)
53
+ → note: "code review"
54
+ → projectId: (look up Project Alpha)
55
+
56
+ User says: "Track 45 minutes of meeting time"
57
+ → duration: 2700 (45 * 60)
58
+ → note: "meeting"
59
+
60
+ User says: "Record 3 hours of development work for client ABC"
61
+ → duration: 10800 (3 * 3600)
62
+ → note: "development work"
63
63
  → clientId: (look up client ABC)`,
64
64
  inputSchema: TimeEntryCreateInputSchema,
65
65
  outputSchema: TimeEntrySingleOutputSchema,
@@ -11,54 +11,54 @@ import { logger } from '../../utils/logger.js';
11
11
  */
12
12
  export const timeentryDeleteTool = {
13
13
  name: 'timeentry_delete',
14
- description: `Delete a time entry from FreshBooks.
15
-
16
- WHEN TO USE:
17
- - User wants to remove a time entry completely
18
- - User says "delete time entry X", "remove entry Y", "discard this time log"
19
- - User made a mistake and wants to delete rather than update
20
- - User wants to discard a running timer without logging the time
21
- - User asks "delete entry 123", "remove that time entry"
22
-
23
- REQUIRED:
24
- - businessId: FreshBooks business ID (get from user_me -> businessMemberships[].business.id)
25
- - timeEntryId: ID of the time entry to delete
26
-
27
- IMPORTANT NOTES:
28
- - Deletion is permanent and cannot be undone
29
- - Use this to discard running timers without logging time
30
- - If time was already billed, deletion may affect invoices
31
- - Consider updating instead of deleting if you just need to change values
32
-
33
- USE CASES:
34
- 1. Discard a running timer:
35
- - Delete the active time entry to discard without logging
36
-
37
- 2. Remove erroneous entry:
38
- - Delete time entries created by mistake
39
-
40
- 3. Clean up test data:
41
- - Remove test or sample time entries
42
-
43
- ALTERNATIVE ACTIONS:
44
- - To change duration/project: Use timeentry_update instead
45
- - To make non-billable: Use timeentry_update with billable=false
46
- - To archive: FreshBooks doesn't support archiving (delete removes completely)
47
-
48
- RETURNS:
49
- Success confirmation with:
50
- - success: true/false
51
- - message: Confirmation message
52
- - timeEntryId: ID of the deleted entry
53
-
54
- EXAMPLES:
55
- User says: "Delete time entry 123"
56
- → timeEntryId: 123
57
-
58
- User says: "Discard timer 456"
59
- → timeEntryId: 456
60
-
61
- User says: "Remove that time entry I just created"
14
+ description: `Delete a time entry from FreshBooks.
15
+
16
+ WHEN TO USE:
17
+ - User wants to remove a time entry completely
18
+ - User says "delete time entry X", "remove entry Y", "discard this time log"
19
+ - User made a mistake and wants to delete rather than update
20
+ - User wants to discard a running timer without logging the time
21
+ - User asks "delete entry 123", "remove that time entry"
22
+
23
+ REQUIRED:
24
+ - businessId: FreshBooks business ID (get from user_me -> businessMemberships[].business.id)
25
+ - timeEntryId: ID of the time entry to delete
26
+
27
+ IMPORTANT NOTES:
28
+ - Deletion is permanent and cannot be undone
29
+ - Use this to discard running timers without logging time
30
+ - If time was already billed, deletion may affect invoices
31
+ - Consider updating instead of deleting if you just need to change values
32
+
33
+ USE CASES:
34
+ 1. Discard a running timer:
35
+ - Delete the active time entry to discard without logging
36
+
37
+ 2. Remove erroneous entry:
38
+ - Delete time entries created by mistake
39
+
40
+ 3. Clean up test data:
41
+ - Remove test or sample time entries
42
+
43
+ ALTERNATIVE ACTIONS:
44
+ - To change duration/project: Use timeentry_update instead
45
+ - To make non-billable: Use timeentry_update with billable=false
46
+ - To archive: FreshBooks doesn't support archiving (delete removes completely)
47
+
48
+ RETURNS:
49
+ Success confirmation with:
50
+ - success: true/false
51
+ - message: Confirmation message
52
+ - timeEntryId: ID of the deleted entry
53
+
54
+ EXAMPLES:
55
+ User says: "Delete time entry 123"
56
+ → timeEntryId: 123
57
+
58
+ User says: "Discard timer 456"
59
+ → timeEntryId: 456
60
+
61
+ User says: "Remove that time entry I just created"
62
62
  → (first get the time entry ID, then delete)`,
63
63
  inputSchema: TimeEntryDeleteInputSchema,
64
64
  outputSchema: TimeEntryDeleteOutputSchema,
@@ -12,59 +12,59 @@ import { buildQueryBuilders } from '../base-tool.js';
12
12
  */
13
13
  export const timeentryListTool = {
14
14
  name: 'timeentry_list',
15
- description: `List time entries from FreshBooks.
16
-
17
- WHEN TO USE:
18
- - User asks to see their time entries, logged hours, or time tracking history
19
- - User wants to review time for a specific project or client
20
- - User needs to find entries within a date range
21
- - User wants to see active/running timers
22
- - User asks "show my time entries", "what time did I log today", "time on project X"
23
-
24
- REQUIRED:
25
- - businessId: FreshBooks business ID (get from user_me -> businessMemberships[].business.id)
26
-
27
- OPTIONAL FILTERS:
28
- - projectId: Filter by specific project
29
- - clientId: Filter by specific client
30
- - taskId: Filter by specific task
31
- - serviceId: Filter by specific service
32
- - active: Filter by active status (true = running timers only)
33
- - billable: Filter by billable status
34
- - billed: Filter by whether already billed
35
- - startedAfter: Show entries after this date (ISO 8601)
36
- - startedBefore: Show entries before this date (ISO 8601)
37
-
38
- SORTING:
39
- - sortBy: Field to sort by (started_at, created_at, duration)
40
- - sortOrder: Sort direction (asc or desc, default: desc for most recent first)
41
-
42
- INCLUDES:
43
- - include: Related data to fetch (client, project, task, service)
44
- - client: Client details associated with the time entry
45
- - project: Project details for the time entry
46
- - task: Task information if assigned
47
- - service: Service type for billing categorization
48
-
49
- PAGINATION:
50
- - page: Page number (default: 1)
51
- - perPage: Results per page (default: 30, max: 100)
52
-
53
- RETURNS:
54
- Array of time entries with:
55
- - duration: Time in seconds
56
- - note: Description of work
57
- - startedAt: When the entry began
58
- - projectId, clientId, taskId, serviceId: Associated entities
59
- - billable, billed: Billing status
60
- - active: Whether timer is currently running
61
- Plus pagination metadata (page, pages, total)
62
-
63
- EXAMPLES:
64
- - "Show my time entries for today"
65
- - "List time logged on project 123"
66
- - "Show billable time entries from last week"
67
- - "Find active timers sorted by duration"
15
+ description: `List time entries from FreshBooks.
16
+
17
+ WHEN TO USE:
18
+ - User asks to see their time entries, logged hours, or time tracking history
19
+ - User wants to review time for a specific project or client
20
+ - User needs to find entries within a date range
21
+ - User wants to see active/running timers
22
+ - User asks "show my time entries", "what time did I log today", "time on project X"
23
+
24
+ REQUIRED:
25
+ - businessId: FreshBooks business ID (get from user_me -> businessMemberships[].business.id)
26
+
27
+ OPTIONAL FILTERS:
28
+ - projectId: Filter by specific project
29
+ - clientId: Filter by specific client
30
+ - taskId: Filter by specific task
31
+ - serviceId: Filter by specific service
32
+ - active: Filter by active status (true = running timers only)
33
+ - billable: Filter by billable status
34
+ - billed: Filter by whether already billed
35
+ - startedAfter: Show entries after this date (ISO 8601)
36
+ - startedBefore: Show entries before this date (ISO 8601)
37
+
38
+ SORTING:
39
+ - sortBy: Field to sort by (started_at, created_at, duration)
40
+ - sortOrder: Sort direction (asc or desc, default: desc for most recent first)
41
+
42
+ INCLUDES:
43
+ - include: Related data to fetch (client, project, task, service)
44
+ - client: Client details associated with the time entry
45
+ - project: Project details for the time entry
46
+ - task: Task information if assigned
47
+ - service: Service type for billing categorization
48
+
49
+ PAGINATION:
50
+ - page: Page number (default: 1)
51
+ - perPage: Results per page (default: 30, max: 100)
52
+
53
+ RETURNS:
54
+ Array of time entries with:
55
+ - duration: Time in seconds
56
+ - note: Description of work
57
+ - startedAt: When the entry began
58
+ - projectId, clientId, taskId, serviceId: Associated entities
59
+ - billable, billed: Billing status
60
+ - active: Whether timer is currently running
61
+ Plus pagination metadata (page, pages, total)
62
+
63
+ EXAMPLES:
64
+ - "Show my time entries for today"
65
+ - "List time logged on project 123"
66
+ - "Show billable time entries from last week"
67
+ - "Find active timers sorted by duration"
68
68
  - "Get time entries with project details included"`,
69
69
  inputSchema: TimeEntryListInputSchema,
70
70
  outputSchema: TimeEntryListOutputSchema,
@@ -11,34 +11,34 @@ import { logger } from '../../utils/logger.js';
11
11
  */
12
12
  export const timeentrySingleTool = {
13
13
  name: 'timeentry_single',
14
- description: `Get a single time entry by ID from FreshBooks.
15
-
16
- WHEN TO USE:
17
- - User wants to see details of a specific time entry
18
- - User references a time entry ID and wants full information
19
- - User asks "show time entry 123", "get details for entry X"
20
- - Need to retrieve a time entry before updating or deleting it
21
-
22
- REQUIRED:
23
- - businessId: FreshBooks business ID (get from user_me -> businessMemberships[].business.id)
24
- - timeEntryId: The ID of the time entry to retrieve
25
-
26
- RETURNS:
27
- Complete time entry object with:
28
- - id: Time entry ID
29
- - duration: Time in seconds
30
- - note: Description of work
31
- - startedAt: When the entry began
32
- - createdAt: When the entry was created
33
- - projectId, clientId, taskId, serviceId: Associated entities
34
- - billable, billed: Billing status
35
- - active: Whether timer is currently running
36
- - timer: Active timer object if running
37
- - All other time entry fields
38
-
39
- EXAMPLES:
40
- - "Show me time entry 456"
41
- - "Get details for time entry ID 789"
14
+ description: `Get a single time entry by ID from FreshBooks.
15
+
16
+ WHEN TO USE:
17
+ - User wants to see details of a specific time entry
18
+ - User references a time entry ID and wants full information
19
+ - User asks "show time entry 123", "get details for entry X"
20
+ - Need to retrieve a time entry before updating or deleting it
21
+
22
+ REQUIRED:
23
+ - businessId: FreshBooks business ID (get from user_me -> businessMemberships[].business.id)
24
+ - timeEntryId: The ID of the time entry to retrieve
25
+
26
+ RETURNS:
27
+ Complete time entry object with:
28
+ - id: Time entry ID
29
+ - duration: Time in seconds
30
+ - note: Description of work
31
+ - startedAt: When the entry began
32
+ - createdAt: When the entry was created
33
+ - projectId, clientId, taskId, serviceId: Associated entities
34
+ - billable, billed: Billing status
35
+ - active: Whether timer is currently running
36
+ - timer: Active timer object if running
37
+ - All other time entry fields
38
+
39
+ EXAMPLES:
40
+ - "Show me time entry 456"
41
+ - "Get details for time entry ID 789"
42
42
  - "What's in time entry 123?"`,
43
43
  inputSchema: TimeEntrySingleInputSchema,
44
44
  outputSchema: TimeEntrySingleOutputSchema,
@@ -11,67 +11,67 @@ import { logger } from '../../utils/logger.js';
11
11
  */
12
12
  export const timeentryUpdateTool = {
13
13
  name: 'timeentry_update',
14
- description: `Update an existing time entry in FreshBooks.
15
-
16
- WHEN TO USE:
17
- - User wants to modify a time entry
18
- - User says "update time entry X", "change the duration", "edit my time log"
19
- - User needs to correct duration, note, or project association
20
- - User wants to stop a running timer (set active=false)
21
- - User asks "update entry 123 to 3 hours", "change project on entry 456"
22
-
23
- REQUIRED:
24
- - businessId: FreshBooks business ID (get from user_me -> businessMemberships[].business.id)
25
- - timeEntryId: ID of the time entry to update
26
-
27
- OPTIONAL (provide only fields to change):
28
- - duration: New duration in seconds
29
- - note: New or updated description
30
- - projectId: Change project association (null to remove)
31
- - clientId: Change client association (null to remove)
32
- - serviceId: Change service association (null to remove)
33
- - taskId: Change task association (null to remove)
34
- - billable: Change billable status
35
- - active: Stop/start timer (false to stop, true to restart)
36
- - isLogged: Change logged status
37
- - startedAt: Change start time
38
- - internal: Change internal work flag
39
- - retainerId: Change retainer association
40
-
41
- COMMON USE CASES:
42
- 1. Stop a running timer:
43
- - Set active=false (duration auto-calculated from startedAt)
44
-
45
- 2. Change duration:
46
- - Set new duration in seconds
47
-
48
- 3. Update note:
49
- - Set new note text
50
-
51
- 4. Change project:
52
- - Set new projectId
53
-
54
- 5. Make non-billable:
55
- - Set billable=false
56
-
57
- RETURNS:
58
- Updated time entry with all fields (including unchanged ones)
59
-
60
- EXAMPLES:
61
- User says: "Update time entry 123 to 3 hours"
62
- → timeEntryId: 123
63
- → duration: 10800
64
-
65
- User says: "Stop timer 456"
66
- → timeEntryId: 456
67
- → active: false
68
-
69
- User says: "Change the note on entry 789 to 'code review'"
70
- → timeEntryId: 789
71
- → note: "code review"
72
-
73
- User says: "Make entry 321 non-billable"
74
- → timeEntryId: 321
14
+ description: `Update an existing time entry in FreshBooks.
15
+
16
+ WHEN TO USE:
17
+ - User wants to modify a time entry
18
+ - User says "update time entry X", "change the duration", "edit my time log"
19
+ - User needs to correct duration, note, or project association
20
+ - User wants to stop a running timer (set active=false)
21
+ - User asks "update entry 123 to 3 hours", "change project on entry 456"
22
+
23
+ REQUIRED:
24
+ - businessId: FreshBooks business ID (get from user_me -> businessMemberships[].business.id)
25
+ - timeEntryId: ID of the time entry to update
26
+
27
+ OPTIONAL (provide only fields to change):
28
+ - duration: New duration in seconds
29
+ - note: New or updated description
30
+ - projectId: Change project association (null to remove)
31
+ - clientId: Change client association (null to remove)
32
+ - serviceId: Change service association (null to remove)
33
+ - taskId: Change task association (null to remove)
34
+ - billable: Change billable status
35
+ - active: Stop/start timer (false to stop, true to restart)
36
+ - isLogged: Change logged status
37
+ - startedAt: Change start time
38
+ - internal: Change internal work flag
39
+ - retainerId: Change retainer association
40
+
41
+ COMMON USE CASES:
42
+ 1. Stop a running timer:
43
+ - Set active=false (duration auto-calculated from startedAt)
44
+
45
+ 2. Change duration:
46
+ - Set new duration in seconds
47
+
48
+ 3. Update note:
49
+ - Set new note text
50
+
51
+ 4. Change project:
52
+ - Set new projectId
53
+
54
+ 5. Make non-billable:
55
+ - Set billable=false
56
+
57
+ RETURNS:
58
+ Updated time entry with all fields (including unchanged ones)
59
+
60
+ EXAMPLES:
61
+ User says: "Update time entry 123 to 3 hours"
62
+ → timeEntryId: 123
63
+ → duration: 10800
64
+
65
+ User says: "Stop timer 456"
66
+ → timeEntryId: 456
67
+ → active: false
68
+
69
+ User says: "Change the note on entry 789 to 'code review'"
70
+ → timeEntryId: 789
71
+ → note: "code review"
72
+
73
+ User says: "Make entry 321 non-billable"
74
+ → timeEntryId: 321
75
75
  → billable: false`,
76
76
  inputSchema: TimeEntryUpdateInputSchema,
77
77
  outputSchema: TimeEntrySingleOutputSchema,
@@ -13,60 +13,60 @@ import { ErrorHandler } from "../../errors/error-handler.js";
13
13
  */
14
14
  export const timerCurrentTool = {
15
15
  name: "timer_current",
16
- description: `Get the currently running timer(s) in FreshBooks.
17
-
18
- WHEN TO USE:
19
- - User asks "what timer is running?", "show my current timer", "am I tracking time?"
20
- - Need to find timer ID before stopping it
21
- - Want to check if any timer is active before starting a new one
22
- - Need to see timer details (duration so far, project, notes)
23
-
24
- HOW IT WORKS:
25
- Searches for time entries with:
26
- - active=true (timer is currently running)
27
- - Returns all matching entries (typically 0 or 1)
28
-
29
- TYPICAL RESULTS:
30
- - 0 timers: No timer is currently running
31
- - 1 timer: The active timer with details
32
- - Multiple timers: Rare, but possible in some FreshBooks configurations
33
-
34
- REQUIRED:
35
- - businessId: FreshBooks business ID (get from user_me -> businessMemberships[].business.id)
36
-
37
- NO ACTIVE TIMER:
38
- If no timer is running, returns:
39
- - activeTimers: [] (empty array)
40
- - count: 0
41
-
42
- ACTIVE TIMER DETAILS:
43
- Each active timer includes:
44
- - id: Time entry ID (use this to stop or discard)
45
- - startedAt: When timer started (ISO 8601 timestamp)
46
- - duration: Current duration in seconds (calculated from start time)
47
- - projectId: Associated project (if any)
48
- - clientId: Associated client (if any)
49
- - note: Work description (if any)
50
- - billable: Whether time is billable
51
- - timer: Nested timer object with isRunning=true
52
-
53
- CALCULATING ELAPSED TIME:
54
- The duration field shows elapsed seconds, but it may not be real-time.
55
- To calculate current elapsed time:
56
- - Parse startedAt timestamp
57
- - Calculate difference from now
58
- - Result is current elapsed time
59
-
60
- EXAMPLE USAGE:
61
- - "Show my current timer"
62
- - "What am I tracking time for?"
63
- - "How long has my timer been running?"
64
- - "Is there a timer running?"
65
-
66
- NEXT STEPS:
67
- If timer is found, you can:
68
- - Stop it: Use timer_stop with the returned id
69
- - Discard it: Use timer_discard with the returned id
16
+ description: `Get the currently running timer(s) in FreshBooks.
17
+
18
+ WHEN TO USE:
19
+ - User asks "what timer is running?", "show my current timer", "am I tracking time?"
20
+ - Need to find timer ID before stopping it
21
+ - Want to check if any timer is active before starting a new one
22
+ - Need to see timer details (duration so far, project, notes)
23
+
24
+ HOW IT WORKS:
25
+ Searches for time entries with:
26
+ - active=true (timer is currently running)
27
+ - Returns all matching entries (typically 0 or 1)
28
+
29
+ TYPICAL RESULTS:
30
+ - 0 timers: No timer is currently running
31
+ - 1 timer: The active timer with details
32
+ - Multiple timers: Rare, but possible in some FreshBooks configurations
33
+
34
+ REQUIRED:
35
+ - businessId: FreshBooks business ID (get from user_me -> businessMemberships[].business.id)
36
+
37
+ NO ACTIVE TIMER:
38
+ If no timer is running, returns:
39
+ - activeTimers: [] (empty array)
40
+ - count: 0
41
+
42
+ ACTIVE TIMER DETAILS:
43
+ Each active timer includes:
44
+ - id: Time entry ID (use this to stop or discard)
45
+ - startedAt: When timer started (ISO 8601 timestamp)
46
+ - duration: Current duration in seconds (calculated from start time)
47
+ - projectId: Associated project (if any)
48
+ - clientId: Associated client (if any)
49
+ - note: Work description (if any)
50
+ - billable: Whether time is billable
51
+ - timer: Nested timer object with isRunning=true
52
+
53
+ CALCULATING ELAPSED TIME:
54
+ The duration field shows elapsed seconds, but it may not be real-time.
55
+ To calculate current elapsed time:
56
+ - Parse startedAt timestamp
57
+ - Calculate difference from now
58
+ - Result is current elapsed time
59
+
60
+ EXAMPLE USAGE:
61
+ - "Show my current timer"
62
+ - "What am I tracking time for?"
63
+ - "How long has my timer been running?"
64
+ - "Is there a timer running?"
65
+
66
+ NEXT STEPS:
67
+ If timer is found, you can:
68
+ - Stop it: Use timer_stop with the returned id
69
+ - Discard it: Use timer_discard with the returned id
70
70
  - Continue running: Do nothing, timer keeps tracking`,
71
71
  inputSchema: TimerCurrentInputSchema,
72
72
  outputSchema: TimerCurrentOutputSchema,