Skip to main content
Glama
pshempel

MCP Time Server Node

by pshempel

next_occurrence

Calculate the next occurrence of a recurring event based on specified patterns like daily, weekly, monthly, or yearly schedules.

Instructions

Find next occurrence of a recurring event

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
patternYesRecurrence pattern
start_fromNoStart searching from
day_of_weekNoFor weekly (0-6, 0=Sunday)
day_of_monthNoFor monthly (1-31)
timeNoTime in HH:mm format
timezoneNoTimezone for calculation (default: system timezone)

Implementation Reference

  • The core handler function implementing the next_occurrence tool logic, including parameter validation, timezone resolution, caching, and delegation to calculation logic.
    export function nextOccurrence(params: NextOccurrenceParams): NextOccurrenceResult { debug.recurrence('nextOccurrence called with params: %O', params); // Validate string length first if (params.start_from && typeof params.start_from === 'string') { validateDateString(params.start_from, 'start_from'); } const config = getConfig(); const fallbackTimezone = config.defaultTimezone; const timezone = resolveTimezone(params.timezone, fallbackTimezone); // Validate timezone if provided if (params.timezone) { debug.validation('Validating timezone: %s', timezone); if (!validateTimezone(timezone)) { debug.error('Invalid timezone: %s', timezone); throw new TimezoneError(`Invalid timezone: ${timezone}`, timezone); } } const cacheKey = getCacheKey(params, fallbackTimezone, timezone); // Use withCache wrapper instead of manual cache management return withCache(cacheKey, CacheTTL.CALCULATIONS, () => { try { const result = calculateNextOccurrence(params, timezone); debug.recurrence('nextOccurrence returning: %O', result); return result; } catch (error) { handleCalculationError(error); } }); }
  • TypeScript type definitions for input parameters (NextOccurrenceParams) and output result (NextOccurrenceResult) used by the handler.
    export interface NextOccurrenceParams { pattern: RecurrencePattern; start_from?: string; day_of_week?: number; day_of_month?: number; time?: string; timezone?: string; } export interface NextOccurrenceResult { next: string; unix: number; days_until: number; }
  • src/index.ts:157-179 (registration)
    MCP tool registration in TOOL_DEFINITIONS array, including the tool name, description, and input schema.
    { name: 'next_occurrence', description: 'Find next occurrence of a recurring event', inputSchema: { type: 'object' as const, properties: { pattern: { type: 'string' as const, enum: ['daily', 'weekly', 'monthly', 'yearly'], description: 'Recurrence pattern', }, start_from: { type: 'string' as const, description: 'Start searching from' }, day_of_week: { type: 'number' as const, description: 'For weekly (0-6, 0=Sunday)' }, day_of_month: { type: 'number' as const, description: 'For monthly (1-31)' }, time: { type: 'string' as const, description: 'Time in HH:mm format' }, timezone: { type: 'string' as const, description: 'Timezone for calculation (default: system timezone)', }, }, required: ['pattern'], }, },
  • src/index.ts:268-274 (registration)
    Mapping of the 'next_occurrence' tool name to the nextOccurrence handler function in TOOL_FUNCTIONS record.
    next_occurrence: (params: unknown) => nextOccurrence(params as Parameters<typeof nextOccurrence>[0]), format_time: (params: unknown) => formatTime(params as Parameters<typeof formatTime>[0]), calculate_business_hours: (params: unknown) => calculateBusinessHours(params as Parameters<typeof calculateBusinessHours>[0]), days_until: (params: unknown) => daysUntil(params as Parameters<typeof daysUntil>[0]), };
  • Internal helper function that performs the core date calculation using the RecurrenceFactory.
    function calculateNextOccurrence( params: NextOccurrenceParams, timezone: string ): NextOccurrenceResult { debug.recurrence('calculateNextOccurrence called with params: %O', params); // Parse start date let startFrom: Date; if (params.start_from) { debug.parse('Parsing start_from: %s', params.start_from); try { startFrom = parseTimeInput(params.start_from, timezone).date; debug.parse('Parsed start_from date: %s', startFrom.toISOString()); } catch { debug.error('Invalid start_from date: %s', params.start_from); throw new DateParsingError('Invalid start_from date', { start_from: params.start_from }); } } else { startFrom = new Date(); } // Map parameters to new format const recurrenceParams = mapToRecurrenceParams(params); recurrenceParams.timezone = timezone; // Calculate next occurrence using factory debug.recurrence('Calculating next occurrence with factory'); const nextDate = factory.calculate(startFrom, recurrenceParams); debug.recurrence('Next occurrence date: %s', nextDate.toISOString()); // Format result const result: NextOccurrenceResult = { next: nextDate.toISOString(), unix: Math.floor(nextDate.getTime() / 1000), days_until: calculateDaysUntil(nextDate, timezone), }; return result; }

Latest Blog Posts

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/pshempel/mcp-time-server-node'

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