create-logged-time
Create a logged time entry to track work hours by specifying person, project, date, and hours. Optionally add task, billable status, and notes for detailed time tracking.
Instructions
Create a new logged time entry for tracking work hours
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| people_id | Yes | The person ID who logged the time | |
| project_id | Yes | The project ID for the logged time | |
| task_id | No | The task ID for the logged time | |
| date | Yes | The date for the logged time (YYYY-MM-DD) | |
| hours | Yes | The number of hours logged | |
| billable | No | Whether the time is billable (1 = billable, 0 = non-billable) | |
| notes | No | Optional notes describing the work done | |
| reference_date | No | Reference date for UI suggestions |
Implementation Reference
- Primary handler for the 'create-logged-time' tool. Defines the tool via createTool() with the name 'create-logged-time', specifies the input schema (people_id, project_id, task_id, date, hours, billable, notes, reference_date), and implements the handler which POSTs to '/logged-time' via floatApi and validates the response against loggedTimeSchema.
// Create new logged time entry export const createLoggedTime = createTool( 'create-logged-time', 'Create a new logged time entry for tracking work hours', z.object({ people_id: z.union([z.string(), z.number()]).describe('The person ID who logged the time'), project_id: z.union([z.string(), z.number()]).describe('The project ID for the logged time'), task_id: z.string().optional().describe('The task ID for the logged time'), date: z.string().describe('The date for the logged time (YYYY-MM-DD)'), hours: z.number().describe('The number of hours logged'), billable: z .union([z.string(), z.number()]) .optional() .describe('Whether the time is billable (1 = billable, 0 = non-billable)'), notes: z.string().optional().describe('Optional notes describing the work done'), reference_date: z.string().optional().describe('Reference date for UI suggestions'), }), async (params) => { const loggedTime = await floatApi.post('/logged-time', params, loggedTimeSchema); return loggedTime; } ); - src/types/float.ts:314-329 (schema)The response/validation schema (loggedTimeSchema) that defines the shape of a logged time entry as returned by the Float API. Used by the handler to validate the API response from POST /logged-time.
export const loggedTimeSchema = z.object({ logged_time_id: z.string().optional(), // Hexadecimal ID from Float API people_id: z.number().optional(), // Person who logged the time project_id: z.number().optional(), // Project the time was logged against task_id: z.string().nullable().optional(), // Task the time was logged against date: z.string().nullable().optional(), // Date the time was logged (YYYY-MM-DD) hours: z.number().nullable().optional(), // Hours logged billable: z.number().nullable().optional(), // 1 = billable, 0 = non-billable notes: z.string().nullable().optional(), // Optional notes describing the work reference_date: z.string().nullable().optional(), // Reference date for UI suggestions locked: z.number().nullable().optional(), // 1 = locked, 0 = unlocked created: z.string().nullable().optional(), // Float API uses 'created', not 'created_at' modified: z.string().nullable().optional(), // Float API uses 'modified', not 'updated_at' created_by: z.number().nullable().optional(), // User ID who created the entry modified_by: z.number().nullable().optional(), // User ID who last modified the entry }); - src/tools/index.ts:154-165 (registration)The 'create-logged-time' tool (exported as createLoggedTime) is imported from the logged-time module and included in the legacyTools array (line 302) and subsequently in the tools/allTools arrays (lines 319, 322) for registration with the MCP server.
import { listLoggedTime, getLoggedTime, createLoggedTime, updateLoggedTime, deleteLoggedTime, bulkCreateLoggedTime, getPersonLoggedTimeSummary, getProjectLoggedTimeSummary, getLoggedTimeTimesheet, getBillableTimeReport, } from './time-management/logged-time.js'; - Input schema (Zod object) for the 'create-logged-time' tool defining the required and optional parameters accepted by the tool.
z.object({ people_id: z.union([z.string(), z.number()]).describe('The person ID who logged the time'), project_id: z.union([z.string(), z.number()]).describe('The project ID for the logged time'), task_id: z.string().optional().describe('The task ID for the logged time'), date: z.string().describe('The date for the logged time (YYYY-MM-DD)'), hours: z.number().describe('The number of hours logged'), billable: z .union([z.string(), z.number()]) .optional() .describe('Whether the time is billable (1 = billable, 0 = non-billable)'), notes: z.string().optional().describe('Optional notes describing the work done'), reference_date: z.string().optional().describe('Reference date for UI suggestions'), }), - src/tools/base.ts:50-104 (helper)The createTool helper function used to define tools. It takes a name, description, Zod schema, and handler function. It wraps the handler with parameter validation and standardized error handling (wrapping results in ToolResponse with success/error fields).
export const createTool = <T, P extends z.ZodType>( name: string, description: string, schema: P, handler: (params: z.infer<P>) => Promise<T> ): { name: string; description: string; inputSchema: P; handler: (params: unknown) => Promise<ToolResponse<T>>; } => { return { name, description, inputSchema: schema, handler: async (params: unknown): Promise<ToolResponse<T>> => { try { const validatedParams = schema.parse(params); const result = await handler(validatedParams); // Extract format from params if available const responseFormat = ((validatedParams as Record<string, unknown>).format as ResponseFormat) || 'json'; return { success: true, data: result, format: responseFormat }; } catch (error) { logger.error(`Error in ${name} tool:`, error); // Handle Float API errors with enhanced formatting if (error instanceof FloatApiError) { return FloatErrorHandler.formatErrorForMcp(error) as ToolResponse<T>; } // Handle parameter validation errors if (error instanceof z.ZodError) { return { success: false, error: `Parameter validation failed: ${error.errors.map((e) => `${e.path.join('.')}: ${e.message}`).join(', ')}`, errorCode: 'PARAMETER_VALIDATION_ERROR', details: { validationErrors: error.errors, }, } as ToolResponse<T>; } // Handle other errors return { success: false, error: error instanceof Error ? error.message : 'Unknown error occurred', errorCode: 'UNKNOWN_ERROR', } as ToolResponse<T>; } }, }; };