UNPKG

celestial-position-mcp

Version:

MCP server for celestial object altitude-azimuth coordinates

226 lines (225 loc) 9.69 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const express_1 = __importDefault(require("express")); const cors_1 = __importDefault(require("cors")); const config_1 = require("./config"); const astronomy_1 = require("./utils/astronomy"); // Create Express app const app = (0, express_1.default)(); // Enable CORS app.use((0, cors_1.default)()); // Parse JSON bodies app.use(express_1.default.json()); // Define MCP compatible endpoint app.post('/mcp', async (req, res) => { try { console.log('Received request:', req.body); // Process MCP request const method = req.body.method || ''; const params = req.body.params || {}; if (method === 'mcp.toolCall') { const toolName = params.name || ''; const args = params.arguments || {}; // Handle each tool if (toolName === 'getCelestialPosition') { const result = await handleGetCelestialPosition(args); res.json({ jsonrpc: '2.0', id: req.body.id, result }); } else if (toolName === 'listCelestialObjects') { const result = handleListCelestialObjects(args); res.json({ jsonrpc: '2.0', id: req.body.id, result }); } else { throw new Error(`Unknown tool: ${toolName}`); } } else if (method === 'mcp.discover') { // Return server tools and capabilities res.json({ jsonrpc: '2.0', id: req.body.id, result: { server: { name: 'CelestialPositionMCP', version: '1.0.0' }, tools: [ { name: 'getCelestialPosition', description: 'Get altitude and azimuth coordinates for a celestial object using system time and configured location (no refraction correction)', inputSchema: { type: 'object', properties: { objectName: { type: 'string', description: 'Name of the celestial object (planet, star, messier object, etc.)' }, useSystemTime: { type: 'boolean', description: 'Whether to use the current system time (true) or a custom time (false)', default: true }, dateTime: { type: 'string', description: 'ISO format date and time for the observation (e.g., "2025-04-15T21:30:00"), only used if useSystemTime is false' } }, required: ['objectName'] } }, { name: 'listCelestialObjects', description: 'Get a list of supported celestial objects by category', inputSchema: { type: 'object', properties: { category: { type: 'string', description: 'Filter by category (planets, stars, dso, all)', default: 'all' } } } } ] } }); } else { throw new Error(`Unknown method: ${method}`); } } catch (error) { console.error('Error processing request:', error); res.status(400).json({ jsonrpc: '2.0', id: req.body.id || null, error: { code: -32000, message: error.message || 'Unknown error' } }); } }); // Handle getCelestialPosition tool async function handleGetCelestialPosition(args) { try { const objectName = args.objectName; const useSystemTime = args.useSystemTime !== false; // Default to true const dateTime = args.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 (0, astronomy_1.getEquatorialCoordinates)(objectName, date); // Use observer location from config const observer = { latitude: config_1.OBSERVER_CONFIG.latitude, longitude: config_1.OBSERVER_CONFIG.longitude, elevation: config_1.OBSERVER_CONFIG.altitude, temperature: 0, // Not used anymore pressure: 0 // Not used anymore }; // Convert to horizontal (altaz) coordinates const altazCoords = (0, astronomy_1.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 - both UTC and local time with proper timezone info const utcTimeString = date.toISOString(); const localTimeString = date.toLocaleString(undefined, { timeZoneName: 'short' }); // Calculate LST (Local Sidereal Time) if needed in future versions // Return the formatted results return { content: [ { type: "text", text: JSON.stringify({ object: objectName, altitude: altazCoords.altitude.toFixed(4) + "°", azimuth: altazCoords.azimuth.toFixed(4) + "°", observationTime: { utc: utcTimeString, local: localTimeString }, systemTime: useSystemTime ? "Yes" : "No", location: `${config_1.OBSERVER_CONFIG.latitude.toFixed(4)}°, ${config_1.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}`); } } // Handle listCelestialObjects tool function handleListCelestialObjects(args) { const category = args.category?.toLowerCase() || 'all'; // Use the astronomy utility function to get objects from catalogs const result = (0, astronomy_1.listCelestialObjects)(category); return { content: [ { type: "text", text: JSON.stringify({ totalObjectCount: result.reduce((sum, cat) => sum + cat.objects.length, 0), categories: result }) } ] }; } // Initialize astronomical catalogs (0, astronomy_1.initializeCatalogs)(); // Start server const PORT = config_1.SERVER_CONFIG.port; app.listen(PORT, () => { console.log(`\n🔭 Celestial Position MCP Server is running!`); console.log(`🚀 Server available at http://${config_1.SERVER_CONFIG.host}:${PORT}/mcp`); console.log(`📍 Using location: ${config_1.OBSERVER_CONFIG.latitude.toFixed(4)}°, ${config_1.OBSERVER_CONFIG.longitude.toFixed(4)}°`); });