celestial-position-mcp
Version:
MCP server for celestial object altitude-azimuth coordinates
104 lines (103 loc) • 4.82 kB
JavaScript
import { MCPTool } from 'mcp-framework';
import { z } from 'zod';
import { OBSERVER_CONFIG } from '../config.js';
import { getEquatorialCoordinates, convertToAltAz } from '../utils/astronomy.js';
class CelestialPositionTool extends MCPTool {
constructor() {
super(...arguments);
this.name = 'getCelestialPosition';
this.description = 'Get altitude and azimuth coordinates for a celestial object using system time and configured location';
this.schema = {
objectName: {
type: z.string(),
description: 'Name of the celestial object (planet, star, messier object, etc.)'
},
useSystemTime: {
type: z.boolean().optional().default(true),
description: 'Whether to use the current system time (true) or a custom time (false)'
},
dateTime: {
type: z.string().optional(),
description: 'ISO format date and time for the observation (e.g., "2025-04-15T21:30:00"), only used if useSystemTime is false'
}
};
}
async execute(params) {
try {
const objectName = params.objectName;
const useSystemTime = params.useSystemTime !== false; // Default to true
const dateTime = params.dateTime;
// Get the date (either system time or provided time)
let date;
if (useSystemTime || !dateTime) {
// Use current system time in UTC
date = new Date();
console.log(`Using current system time: ${date.toISOString()}`);
}
else {
// Parse the provided dateTime string
try {
// If the string contains 'Z', treat as UTC time
// If it contains '+' or '-', respect the timezone offset
// Otherwise, interpret as local time
date = new Date(dateTime);
if (isNaN(date.getTime())) {
throw new Error('Invalid date format');
}
console.log(`Using custom time: ${date.toISOString()} (parsed from ${dateTime})`);
}
catch (error) {
throw new Error(`Invalid date format: ${dateTime}. Use ISO format like "2025-04-15T21:30:00Z" for UTC time or "2025-04-15T21:30:00" for local time.`);
}
}
// Get equatorial coordinates for the object
const equatorialCoords = await getEquatorialCoordinates(objectName, date);
// Use observer location from config
const observer = {
latitude: OBSERVER_CONFIG.latitude,
longitude: OBSERVER_CONFIG.longitude,
elevation: OBSERVER_CONFIG.altitude,
temperature: OBSERVER_CONFIG.temperature,
pressure: OBSERVER_CONFIG.pressure
};
// Convert to horizontal (altaz) coordinates
const altazCoords = convertToAltAz(equatorialCoords, observer, date);
// Calculate additional information
const isAboveHorizon = altazCoords.altitude > 0;
const visibility = isAboveHorizon
? altazCoords.altitude > 30
? "Excellent visibility"
: "Above horizon"
: "Below horizon (not visible)";
// Format time information
const utcTimeString = date.toISOString();
const localTimeString = date.toLocaleString(undefined, {
timeZoneName: 'short'
});
// Return the formatted results
return {
object: objectName,
altitude: altazCoords.altitude.toFixed(4) + "°",
azimuth: altazCoords.azimuth.toFixed(4) + "°",
observationTime: {
utc: utcTimeString,
local: localTimeString
},
systemTime: useSystemTime ? "Yes" : "No",
location: `${OBSERVER_CONFIG.latitude.toFixed(4)}°, ${OBSERVER_CONFIG.longitude.toFixed(4)}°`,
aboveHorizon: isAboveHorizon ? "Yes" : "No",
visibility: visibility,
equatorialCoordinates: {
rightAscension: equatorialCoords.rightAscension.toFixed(4) + "h",
declination: equatorialCoords.declination.toFixed(4) + "°"
},
refractionApplied: false
};
}
catch (error) {
throw new Error(`Failed to calculate celestial position: ${error.message}`);
}
}
}
// Export the class, not an instance
export default CelestialPositionTool;