Skip to main content
Glama

Crew Qualifications & Certifications MCP Server

by jbandu
calculate-crew-pay.ts6.18 kB
/** * MCP Tool: calculate-crew-pay * Calculate crew member pay for a given period */ import { z } from 'zod'; import { PayCalculator } from '../engines/pay-calculator.js'; import { getCrewMember, insertPayRecord } from '../db/queries.js'; import type { MCPToolResponse } from '../types/mcp.js'; import { logger } from '../utils/logger.js'; // Input validation schema const CalculateCrewPaySchema = z.object({ crew_identifier: z.string().min(1), pay_period_start: z.string().date(), pay_period_end: z.string().date(), include_breakdown: z.boolean().optional().default(true), }); // Tool definition export const calculateCrewPayTool = { name: 'calculate-crew-pay', description: 'Calculate crew member pay for a given period using automated rules engine with union contract compliance', inputSchema: { type: 'object', properties: { crew_identifier: { type: 'string', description: 'Employee number or crew_id', }, pay_period_start: { type: 'string', format: 'date', description: 'Pay period start date', }, pay_period_end: { type: 'string', format: 'date', description: 'Pay period end date', }, include_breakdown: { type: 'boolean', description: 'Include detailed calculation breakdown', default: true, }, }, required: ['crew_identifier', 'pay_period_start', 'pay_period_end'], }, }; // Tool handler export async function handleCalculateCrewPay( args: unknown ): Promise<MCPToolResponse> { try { // Validate input const params = CalculateCrewPaySchema.parse(args); logger.info('Calculating crew pay', { crew_identifier: params.crew_identifier, period: `${params.pay_period_start} to ${params.pay_period_end}`, }); // Get crew member const crewMember = await getCrewMember(params.crew_identifier); if (!crewMember) { return { content: [ { type: 'text', text: `Crew member not found: ${params.crew_identifier}`, }, ], isError: true, }; } // Calculate pay const calculator = new PayCalculator(); const calculation = await calculator.calculatePay( crewMember.crew_id, new Date(params.pay_period_start), new Date(params.pay_period_end) ); // Save pay record to database try { await insertPayRecord({ crew_id: crewMember.crew_id, pay_period_start: new Date(params.pay_period_start), pay_period_end: new Date(params.pay_period_end), flight_hours: calculation.summary.total_flight_hours, duty_hours: calculation.summary.total_duty_hours, base_pay: calculation.breakdown.base_pay.amount, per_diem: calculation.breakdown.per_diem.amount, premium_pay: calculation.breakdown.premium_pay.reduce( (sum, p) => sum + p.amount, 0 ), overtime_pay: calculation.breakdown.overtime_pay.amount, guarantee_pay: calculation.breakdown.guarantee_pay.amount, total_compensation: calculation.summary.total_compensation, calculation_method: 'AUTOMATED', verified: false, notes: `Calculated via MCP tool at ${new Date().toISOString()}`, }); logger.info('Pay record saved to database'); } catch (error) { logger.warn('Failed to save pay record to database:', error); // Continue - calculation is still valid even if save fails } // Format response let response: any = { crew_member: calculation.crew_member, pay_period: { start: params.pay_period_start, end: params.pay_period_end, }, summary: { total_flight_hours: calculation.summary.total_flight_hours.toFixed(2), total_duty_hours: calculation.summary.total_duty_hours.toFixed(2), total_compensation: `$${calculation.summary.total_compensation.toFixed(2)}`, }, calculation_timestamp: calculation.calculation_timestamp, }; if (params.include_breakdown) { response.breakdown = { base_pay: { amount: `$${calculation.breakdown.base_pay.amount.toFixed(2)}`, hours: calculation.breakdown.base_pay.hours?.toFixed(2), rate: `$${calculation.breakdown.base_pay.rate.toFixed(2)}/hr`, description: calculation.breakdown.base_pay.description, }, per_diem: { amount: `$${calculation.breakdown.per_diem.amount.toFixed(2)}`, hours: calculation.breakdown.per_diem.hours?.toFixed(2), rate: `$${calculation.breakdown.per_diem.rate.toFixed(2)}/hr`, description: calculation.breakdown.per_diem.description, }, premium_pay: calculation.breakdown.premium_pay.map((p) => ({ type: p.type, amount: `$${p.amount.toFixed(2)}`, description: p.description, })), overtime_pay: { amount: `$${calculation.breakdown.overtime_pay.amount.toFixed(2)}`, description: calculation.breakdown.overtime_pay.description, }, guarantee_pay: { amount: `$${calculation.breakdown.guarantee_pay.amount.toFixed(2)}`, description: calculation.breakdown.guarantee_pay.description, }, }; response.applied_rules = calculation.applied_rules.map((rule) => ({ rule_name: rule.rule_name, rule_type: rule.rule_type, amount: `$${rule.amount.toFixed(2)}`, })); response.duty_records_count = calculation.duty_records.length; } logger.info('Crew pay calculation complete', { crew_id: crewMember.crew_id, total_compensation: calculation.summary.total_compensation, }); return { content: [ { type: 'text', text: JSON.stringify(response, null, 2), }, ], }; } catch (error) { logger.error('Error calculating crew pay:', error); return { content: [ { type: 'text', text: `Error: ${error instanceof Error ? error.message : String(error)}`, }, ], isError: true, }; } }

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/jbandu/crew-mcp'

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