get_sun_times
Retrieve sunrise, sunset, and other sun event times for a specific date and location using latitude, longitude, and optional timezone. Outputs in JSON or text format.
Instructions
Get sun rise/set and other sun event times for a specific date and location
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| date | No | Date to get sun times for (YYYY-MM-DD format). Defaults to current date. | |
| format | No | Output format (json or text) | |
| latitude | Yes | Latitude for location-specific calculations | |
| longitude | Yes | Longitude for location-specific calculations | |
| timezone | No | Timezone for the results. Defaults to UTC. |
Implementation Reference
- src/tools/sun-tools.ts:19-39 (handler)The MCP tool's execute handler: calls sunService.getSunTimes(params), formats output as text or JSON based on params.format, handles errors.execute: async (params) => { try { const result = sunService.getSunTimes(params); if (params.format === 'text') { let text = `Sun times for ${result.date} at latitude ${params.latitude}, longitude ${params.longitude}:\n`; text += `Sunrise: ${result.sunrise || 'N/A'}\n`; text += `Sunset: ${result.sunset || 'N/A'}\n`; text += `Day length: ${Math.floor(result.dayLength / 60)}h ${Math.round(result.dayLength % 60)}m\n`; text += `Solar noon: ${result.solarNoon || 'N/A'}\n`; text += `Dawn: ${result.dawn || 'N/A'}\n`; text += `Dusk: ${result.dusk || 'N/A'}\n`; return text; } return JSON.stringify(result); } catch (error) { if (error instanceof Error) { throw new Error(`Failed to get sun times: ${error.message}`); } throw new Error('Failed to get sun times'); } }
- src/interfaces/sun.ts:7-15 (schema)Zod schema defining input parameters for the get_sun_times tool, including date, location, format, and timezone.export const SunTimesParamsSchema = z.object({ date: z.string().optional().describe('Date to get sun times for (YYYY-MM-DD format). Defaults to current date.'), latitude: z.number().min(-90).max(90).describe('Latitude for location-specific calculations'), longitude: z.number().min(-180).max(180).describe('Longitude for location-specific calculations'), format: z.enum(['json', 'text']).optional().describe('Output format (json or text)'), timezone: z.string().optional().describe('Timezone for the results. Defaults to UTC.') }); export type SunTimesParams = z.infer<typeof SunTimesParamsSchema>;
- src/tools/sun-tools.ts:15-40 (registration)Registers the 'get_sun_times' tool with the FastMCP server using server.addTool, specifying name, description, parameters schema, and execute handler.server.addTool({ name: 'get_sun_times', description: 'Get sun rise/set and other sun event times for a specific date and location', parameters: SunTimesParamsSchema, execute: async (params) => { try { const result = sunService.getSunTimes(params); if (params.format === 'text') { let text = `Sun times for ${result.date} at latitude ${params.latitude}, longitude ${params.longitude}:\n`; text += `Sunrise: ${result.sunrise || 'N/A'}\n`; text += `Sunset: ${result.sunset || 'N/A'}\n`; text += `Day length: ${Math.floor(result.dayLength / 60)}h ${Math.round(result.dayLength % 60)}m\n`; text += `Solar noon: ${result.solarNoon || 'N/A'}\n`; text += `Dawn: ${result.dawn || 'N/A'}\n`; text += `Dusk: ${result.dusk || 'N/A'}\n`; return text; } return JSON.stringify(result); } catch (error) { if (error instanceof Error) { throw new Error(`Failed to get sun times: ${error.message}`); } throw new Error('Failed to get sun times'); } } });
- src/services/sun-service.ts:14-63 (helper)SunService.getSunTimes method: computes detailed sun event times using SunCalc.getTimes, handles time formatting and timezone, calculates day length.getSunTimes(params: SunTimesParams): SunTimesInfo { const date = params.date ? new Date(params.date) : new Date(); const { latitude, longitude } = params; // Get sun times data const sunTimes = SunCalc.getTimes(date, latitude, longitude); // Format times or return null if not available const formatTime = (time: Date | null): string | null => { if (!time || isNaN(time.getTime())) return null; if (params.timezone) { try { return time.toLocaleTimeString('en-US', { timeZone: params.timezone }); } catch (error) { // If timezone is invalid, fall back to ISO string console.warn(`Invalid timezone: ${params.timezone}. Using UTC.`); } } return time.toISOString(); }; // Calculate day length in minutes const sunrise = sunTimes.sunrise; const sunset = sunTimes.sunset; let dayLength = 0; if (sunrise && sunset && !isNaN(sunrise.getTime()) && !isNaN(sunset.getTime())) { dayLength = (sunset.getTime() - sunrise.getTime()) / (60 * 1000); } return { date: date.toISOString().split('T')[0], sunrise: formatTime(sunTimes.sunrise), sunset: formatTime(sunTimes.sunset), solarNoon: formatTime(sunTimes.solarNoon), dawn: formatTime(sunTimes.dawn), dusk: formatTime(sunTimes.dusk), nightStart: formatTime(sunTimes.night), nightEnd: formatTime(sunTimes.nightEnd), goldenHourStart: formatTime(sunTimes.goldenHour), goldenHourEnd: formatTime(sunTimes.goldenHourEnd), nauticalDawn: formatTime(sunTimes.nauticalDawn), nauticalDusk: formatTime(sunTimes.nauticalDusk), astronomicalDawn: formatTime(sunTimes.astronomicalDawn), astronomicalDusk: formatTime(sunTimes.astronomicalDusk), dayLength }; }
- src/tools/index.ts:28-29 (registration)Top-level registration call to registerSunTools which includes the get_sun_times tool.registerMoonTools(server, moonPhaseService); registerSunTools(server, sunService);