nasa_mars_rover
Access and retrieve Mars rover photos by specifying rover name, date, and camera to explore Martian terrain through NASA's image database.
Instructions
NASA Mars Rover Photos - images from Mars rovers
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| rover | Yes | Name of the rover (curiosity, opportunity, spirit, perseverance) | |
| sol | No | Martian sol (day) of the photos | |
| earth_date | No | Earth date of the photos (YYYY-MM-DD) | |
| camera | No | Camera name | |
| page | No | Page number for pagination |
Implementation Reference
- src/handlers/nasa/mars_rover.ts:19-49 (handler)Main handler function that executes the nasa_mars_rover tool: validates params, calls NASA API, processes results.export async function nasaMarsRoverHandler(params: MarsRoverParams) { try { const { rover, ...queryParams } = params; // Call the NASA Mars Rover Photos API const result = await nasaApiRequest(`/mars-photos/api/v1/rovers/${rover}/photos`, queryParams); // Process the results and register resources return processRoverResults(result, rover); } catch (error: any) { console.error('Error in Mars Rover handler:', error); if (error.name === 'ZodError') { return { content: [{ type: "text", text: `Invalid request parameters: ${JSON.stringify(error.errors)}` }], isError: true }; } return { content: [{ type: "text", text: `Error fetching Mars Rover photos: ${error.message || 'Unknown error'}` }], isError: true }; } }
- Helper function to process rover API results: fetches images, registers nasa://mars_rover/photo resources, formats MCP response.async function processRoverResults(data: any, rover: string) { const photos = data.photos || []; const resources = []; // Collect base64 image data for direct display const images: Array<{ title: string; url: string; data: string; mimeType: string }> = []; if (photos.length === 0) { return { content: [{ type: "text", text: `No photos found for rover ${rover} with the specified parameters.` }], isError: false }; } // Register each photo as a resource for (const photo of photos) { const photoId = photo.id.toString(); const resourceUri = `nasa://mars_rover/photo?rover=${rover}&id=${photoId}`; try { // Fetch the actual image data const imageResponse = await axios({ url: photo.img_src, responseType: 'arraybuffer', timeout: 30000 }); // Convert image data to Base64 const imageBase64 = Buffer.from(imageResponse.data).toString('base64'); // Register the resource with binary data in the blob field addResource(resourceUri, { name: `Mars Rover Photo ${photoId}`, mimeType: "image/jpeg", // Store metadata as text for reference text: JSON.stringify({ photo_id: photoId, rover: rover, camera: photo.camera?.name || 'Unknown', earth_date: photo.earth_date, sol: photo.sol, img_src: photo.img_src }), // Store the actual image data as a blob blob: Buffer.from(imageResponse.data) }); // Keep base64 data for direct response images.push({ title: `Mars Rover Photo ${photoId}`, url: photo.img_src, data: imageBase64, mimeType: "image/jpeg" }); } catch (error) { console.error(`Error fetching image for rover photo ${photoId}:`, error); // If fetching fails, register with just the metadata and URL addResource(resourceUri, { name: `Mars Rover Photo ${photoId}`, mimeType: "image/jpeg", text: JSON.stringify({ photo_id: photoId, rover: rover, camera: photo.camera?.name || 'Unknown', img_src: photo.img_src, earth_date: photo.earth_date, sol: photo.sol, fetch_error: (error as Error).message }) }); } resources.push({ title: `Mars Rover Photo ${photoId}`, description: `Photo taken by ${rover} rover on Mars`, resource_uri: resourceUri }); } // Format the response for MCP return { content: [ { type: "text", text: `Found ${photos.length} photos from Mars rover ${rover}.` }, { type: "text", text: JSON.stringify(resources, null, 2) }, // Include direct image links and binary data ...images.map(img => ({ type: "text", text: `` })), ...images.map(img => ({ type: "image", data: img.data, mimeType: img.mimeType })), ], isError: false }; }
- src/handlers/setup.ts:114-120 (schema)Zod schema defining input parameters for Mars Rover tool (MarsRoverParams), imported and used by handler.const MarsRoverSchema = z.object({ rover: z.enum(['curiosity', 'opportunity', 'perseverance', 'spirit']), sol: z.number().int().nonnegative().optional(), earth_date: z.string().optional(), camera: z.string().optional(), page: z.number().int().positive().optional() });
- src/index.ts:1526-1540 (registration)Registers direct MCP request handler for method 'nasa/mars-rover', validates params inline, dispatches to handleToolCall.server.setRequestHandler( z.object({ method: z.literal("nasa/mars-rover"), params: z.object({ rover: z.enum(['curiosity', 'opportunity', 'perseverance', 'spirit']), sol: z.number().int().nonnegative().optional(), earth_date: z.string().optional(), camera: z.string().optional(), page: z.number().int().positive().optional() }).optional() }), async (request) => { return await handleToolCall("nasa/mars-rover", request.params || {}); } );
- src/index.ts:935-963 (registration)Registers 'nasa_mars_rover' tool in tools/list response with full input schema definition.name: "nasa_mars_rover", description: "NASA Mars Rover Photos - images from Mars rovers", inputSchema: { type: "object", properties: { rover: { type: "string", description: "Name of the rover (curiosity, opportunity, spirit, perseverance)" }, sol: { type: "number", description: "Martian sol (day) of the photos" }, earth_date: { type: "string", description: "Earth date of the photos (YYYY-MM-DD)" }, camera: { type: "string", description: "Camera name" }, page: { type: "number", description: "Page number for pagination" } }, required: ["rover"] } },