Skip to main content
Glama

nasa_neo

Search for asteroids near Earth by date range or specific ID to monitor potential impact risks using NASA's Near Earth Object data.

Instructions

Near Earth Object Web Service - information about asteroids

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
start_dateYesStart date for asteroid search (YYYY-MM-DD)
end_dateYesEnd date for asteroid search (YYYY-MM-DD)
asteroid_idNoID of a specific asteroid

Implementation Reference

  • Core handler function `nasaNeoHandler` that executes the nasa_neo tool logic: fetches NEO data by date range or asteroid ID from NASA API, stores as resource, formats output.
    export async function nasaNeoHandler(params: NeoParams) {
      try {
        // If we're looking for a specific asteroid by ID
        if (params.asteroid_id) {
          const endpoint = `/neo/rest/v1/neo/${params.asteroid_id}`;
          const result = await nasaApiRequest(endpoint, {});
          
          // Store the result as a resource
          addResource(`nasa://neo/${params.asteroid_id}`, {
            name: `Asteroid: ${result.name}`,
            mimeType: 'application/json',
            text: JSON.stringify(result, null, 2)
          });
          
          // Return formatted result
          return {
            content: [
              {
                type: "text",
                text: formatSingleAsteroidText(result)
              }
            ],
            isError: false
          };
        }
        
        // Default to today if no dates specified
        let startDate = params.start_date;
        let endDate = params.end_date;
        
        if (!startDate) {
          const today = new Date();
          startDate = today.toISOString().split('T')[0];
        }
        
        // If no end_date, use start_date (same day)
        if (!endDate) {
          endDate = startDate;
        }
        
        // API limits feed to 7 days
        const maxDays = 7;
        const start = new Date(startDate);
        const end = new Date(endDate);
        const daysDiff = Math.floor((end.getTime() - start.getTime()) / (1000 * 60 * 60 * 24));
        
        if (daysDiff > maxDays) {
          return {
            content: [
              {
                type: "text",
                text: `Error: Date range too large. NEO feed is limited to ${maxDays} days.`
              }
            ],
            isError: true
          };
        }
        
        // Call the NASA NEO API
        const endpoint = `/neo/rest/v1/feed?start_date=${startDate}&end_date=${endDate}`;
        const result = await nasaApiRequest(endpoint, {});
        
        // Process and format the results
        return processNeoFeedResults(result, startDate, endDate);
      } catch (error: any) {
        console.error('Error in NEO handler:', error);
        
        return {
          content: [
            {
              type: "text",
              text: `Error retrieving NEO data: ${error.message}`
            }
          ],
          isError: true
        };
      }
    }
  • Zod schema `neoParamsSchema` defining input parameters for the nasa_neo tool.
    export const neoParamsSchema = z.object({
      start_date: z.string().optional(),
      end_date: z.string().optional(),
      asteroid_id: z.string().optional()
    });
  • src/index.ts:728-748 (registration)
    Tool `nasa_neo` definition and input schema in the `tools/list` handler response.
      name: "nasa_neo",
      description: "Near Earth Object Web Service - information about asteroids",
      inputSchema: {
        type: "object",
        properties: {
          start_date: {
            type: "string",
            description: "Start date for asteroid search (YYYY-MM-DD)"
          },
          end_date: {
            type: "string",
            description: "End date for asteroid search (YYYY-MM-DD)"
          },
          asteroid_id: {
            type: "string",
            description: "ID of a specific asteroid"
          }
        },
        required: ["start_date", "end_date"]
      }
    },
  • src/index.ts:1496-1509 (registration)
    Direct MCP request handler registration for method `nasa/neo`, dispatching to `handleToolCall`.
    // NEO Handler
    server.setRequestHandler(
      z.object({ 
        method: z.literal("nasa/neo"),
        params: z.object({
          start_date: z.string().optional(),
          end_date: z.string().optional(),
          asteroid_id: z.string().optional()
        }).optional()
      }),
      async (request) => {
        return await handleToolCall("nasa/neo", request.params || {});
      }
    );
  • src/index.ts:1853-1895 (registration)
    Dynamic handler loading in `handleToolCall`: imports `./handlers/nasa/neo.js` and calls default export (`nasaNeoHandler`) for `nasa_neo` tool.
    if (internalToolId.startsWith("nasa/")) {
      // Extract the NASA API endpoint name
      const endpoint = internalToolId.split("/")[1];
      const normalizedEndpoint = endpoint.replace(/-/g, '_'); // Normalize dashes for handler lookup if needed
    
      // Log endpoint for debugging
      serverInstance?.sendLoggingMessage({
        level: "info",
        data: `NASA Endpoint: ${endpoint} (Normalized: ${normalizedEndpoint})`,
      });
    
      try {
        // Dynamic import for NASA handlers using the original slash format path
        const handlerModule = await import(`./handlers/nasa/${endpoint}.js`);
        serverInstance?.sendLoggingMessage({
          level: "info",
          data: `Successfully imported handler module for: ./handlers/nasa/${endpoint}.js`,
        });
    
        // Try different potential handler function names
        const handlerFunctionName = `nasa${endpoint.charAt(0).toUpperCase() + endpoint.slice(1).replace(/-/g, '_')}Handler`; // e.g. nasaMars_roverHandler
        const simpleHandlerName = `${endpoint.replace(/-/g, '_')}Handler`; // e.g. mars_roverHandler
    
        const handlerFunction = handlerModule.default || 
                               handlerModule[handlerFunctionName] || 
                               handlerModule[simpleHandlerName];
    
        if (typeof handlerFunction === 'function') {
          serverInstance?.sendLoggingMessage({
            level: "info",
            data: `Executing handler function for ${endpoint}`,
          });
          return await handlerFunction(args);
        } else {
          serverInstance?.sendLoggingMessage({
            level: "info",
            data: `No handler function found in module: ${JSON.stringify(Object.keys(handlerModule))}`,
          });
          throw new Error(`No handler function found for NASA endpoint: ${normalizedEndpoint}`);
        }
      } catch (importError) {
        throw new Error(`Failed to import handler for NASA endpoint: ${normalizedEndpoint}. Error: ${importError instanceof Error ? importError.message : String(importError)}`);
      }

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