Skip to main content
Glama

jpl_horizons

Access ephemeris data for solar system objects to calculate positions and orbits for astronomical observations and research.

Instructions

JPL Horizons - Solar system objects ephemeris data

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
formatNoResponse format (json, text)
COMMANDYesTarget object identifier (e.g., '499' for Mars, '1' for Ceres, 'C/2020 F3' for Comet NEOWISE)
OBJ_DATANoInclude object data
MAKE_EPHEMNoGenerate ephemeris
EPHEM_TYPENoType of ephemeris (OBSERVER, VECTORS, ELEMENTS)
CENTERNoCoordinate center (e.g., '500@399' for Earth)
START_TIMENoStart time for ephemeris (e.g., '2023-01-01')
STOP_TIMENoStop time for ephemeris (e.g., '2023-01-02')
STEP_SIZENoStep size for ephemeris points (e.g., '1d' for daily, '1h' for hourly)
QUANTITIESNoObservable quantities to include (e.g., 'A' for all, or '1,2,20,23' for specific ones)
OUT_UNITSNoOutput units for vector tables

Implementation Reference

  • Core handler function `horizonsHandler` that executes the JPL Horizons API request using axios, customizes resource metadata based on parameters like COMMAND and EPHEM_TYPE, adds the JSON response as a jpl://horizons resource, and returns formatted content or error.
    export async function horizonsHandler(args: Record<string, any>) { try { // Base URL for the Horizons API const baseUrl = 'https://ssd.jpl.nasa.gov/api/horizons.api'; // Make the API request const response = await axios.get(baseUrl, { params: args }); const data = response.data; // Create a resource URI that represents this query let resourceUri = 'jpl://horizons'; let resourceName = 'JPL Horizons ephemeris data'; // Customize resource name based on the request type if (args.COMMAND) { // Add the object identifier to the resource URI resourceUri += `/object/${encodeURIComponent(args.COMMAND)}`; // Update resource name based on EPHEM_TYPE if (args.EPHEM_TYPE === 'OBSERVER') { resourceName = `${args.COMMAND} observer ephemeris data`; } else if (args.EPHEM_TYPE === 'VECTORS') { resourceName = `${args.COMMAND} vector ephemeris data`; } else if (args.EPHEM_TYPE === 'ELEMENTS') { resourceName = `${args.COMMAND} orbital elements data`; } else { resourceName = `${args.COMMAND} ephemeris data`; } // Add time range info if available if (args.START_TIME && args.STOP_TIME) { resourceName += ` (${args.START_TIME} to ${args.STOP_TIME})`; } } // Add query parameters to the URI const queryParams = Object.entries(args) .filter(([key]) => key !== 'COMMAND' && key !== 'format') .map(([key, value]) => `${key}=${encodeURIComponent(String(value))}`) .join('&'); if (queryParams) { resourceUri += `?${queryParams}`; } // Add response to resources addResource(resourceUri, { name: resourceName, mimeType: "application/json", text: JSON.stringify(data, null, 2) }); // Format the response return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] }; } catch (error: any) { return { content: [{ type: "text", text: `Error accessing JPL Horizons API: ${error.message}` }], isError: true }; } }
  • src/index.ts:1231-1287 (registration)
    Registration of the 'jpl_horizons' tool in the tools/list handler response, including full name, description, and detailed inputSchema for parameter validation (e.g., COMMAND required, EPHEM_TYPE enum).
    name: "jpl_horizons", description: "JPL Horizons - Solar system objects ephemeris data", inputSchema: { type: "object", properties: { format: { type: "string", description: "Response format (json, text)", enum: ["json", "text"] }, COMMAND: { type: "string", description: "Target object identifier (e.g., '499' for Mars, '1' for Ceres, 'C/2020 F3' for Comet NEOWISE)" }, OBJ_DATA: { type: "string", description: "Include object data", enum: ["YES", "NO"] }, MAKE_EPHEM: { type: "string", description: "Generate ephemeris", enum: ["YES", "NO"] }, EPHEM_TYPE: { type: "string", description: "Type of ephemeris (OBSERVER, VECTORS, ELEMENTS)", enum: ["OBSERVER", "VECTORS", "ELEMENTS"] }, CENTER: { type: "string", description: "Coordinate center (e.g., '500@399' for Earth)" }, START_TIME: { type: "string", description: "Start time for ephemeris (e.g., '2023-01-01')" }, STOP_TIME: { type: "string", description: "Stop time for ephemeris (e.g., '2023-01-02')" }, STEP_SIZE: { type: "string", description: "Step size for ephemeris points (e.g., '1d' for daily, '1h' for hourly)" }, QUANTITIES: { type: "string", description: "Observable quantities to include (e.g., 'A' for all, or '1,2,20,23' for specific ones)" }, OUT_UNITS: { type: "string", description: "Output units for vector tables", enum: ["KM-S", "AU-D", "KM-D"] } }, required: ["COMMAND"] }
  • src/index.ts:533-536 (registration)
    Brief registration of 'jpl_horizons' tool in the tools/manifest API response with id 'jpl/horizons'.
    name: "jpl_horizons", id: "jpl/horizons", description: "JPL Horizons - Solar system objects ephemeris data" },
  • Dynamic import and dispatch logic in handleToolCall for JPL tools: imports `./handlers/jpl/horizons.js` (endpoint='horizons') and executes its default export handler function with the provided arguments.
    // Extract the JPL API endpoint name const endpoint = internalToolId.split("/")[1]; serverInstance?.sendLoggingMessage({ level: "info", data: `JPL Endpoint: ${endpoint}`, }); try { // Dynamic import for JPL handlers using the original slash format path serverInstance?.sendLoggingMessage({ level: "info", data: `Importing handler module: ./handlers/jpl/${endpoint}.js`, }); const handlerModule = await import(`./handlers/jpl/${endpoint}.js`); // Try to find the handler function in various export formats const handlerFunction = handlerModule.default || handlerModule[`jpl${endpoint.charAt(0).toUpperCase() + endpoint.slice(1)}Handler`] || handlerModule[`${endpoint}Handler`]; if (typeof handlerFunction === 'function') { return await handlerFunction(args); } else { throw new Error(`Handler for ${endpoint} not found in module`); } } catch (error: unknown) { const errorMessage = error instanceof Error ? error.message : String(error); return { content: [{ type: "text", text: `Error executing JPL tool '${toolName}': ${errorMessage}` }], isError: true }; } }
  • src/index.ts:2142-2148 (registration)
    Global MCP tool registration for 'mcp__jplhorizons' that delegates to handleToolCall('jpl/horizons', args).
    registerGlobalTool('mcp__jplhorizons', async (args: Record<string, any>) => { serverInstance?.sendLoggingMessage({ level: "info", data: `MCP JPL Horizons called with args: ${JSON.stringify(args)}`, }); return await handleToolCall('jpl/horizons', args); });

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/ProgramComputer/NASA-MCP-server'

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