Skip to main content
Glama

get_mars_rover_manifest

Retrieve mission manifests for Mars rovers to access landing dates, operational status, photo counts, and detailed mission timelines.

Instructions

Get the mission manifest for a Mars rover (Curiosity, Opportunity, Spirit). Provides mission details like landing/launch dates, status, max sol/date, total photos, and photo counts per sol.

Args: rover_name: Name of the rover (curiosity, opportunity, spirit).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
rover_nameYes

Implementation Reference

  • The handler function implementing the get_mars_rover_manifest tool. It validates the rover name, fetches the manifest from NASA's Mars Rover Photos API, and formats the mission details including status, dates, total photos, and photo counts per sol (showing latest 5).
    async def get_mars_rover_manifest(rover_name: str) -> str: """Get the mission manifest for a Mars rover (Curiosity, Opportunity, Spirit). Provides mission details like landing/launch dates, status, max sol/date, total photos, and photo counts per sol. Args: rover_name: Name of the rover (curiosity, opportunity, spirit). """ rover_name = rover_name.lower() if rover_name not in ROVER_CAMERAS: return f"Invalid rover name. Available rovers: {', '.join(ROVER_CAMERAS.keys())}" url = f"{NASA_API_BASE}/mars-photos/api/v1/manifests/{rover_name}" data = await make_nasa_request(url) if not data: return f"Could not retrieve mission manifest for {rover_name} due to a connection error." # Check for error response (must be a dictionary) if isinstance(data, dict) and "error" in data: return f"API Error: {data.get('error')} - Details: {data.get('details', 'N/A')}" if isinstance(data, dict) and data.get("binary_content"): return f"Received unexpected binary content from Mars Rover Manifest API. URL: {data.get('url')}" # Response should be a dictionary containing 'photo_manifest' if not isinstance(data, dict) or "photo_manifest" not in data: logger.error(f"Unexpected response format from Mars Rover Manifest API: {data}") return "Received unexpected data format from Mars Rover Manifest API." try: manifest = data.get("photo_manifest", {}) result = [ f"Mission Manifest for Rover: {manifest.get('name', 'Unknown')}", f"Status: {manifest.get('status', 'Unknown')}", f"Launch Date: {manifest.get('launch_date', 'Unknown')}", f"Landing Date: {manifest.get('landing_date', 'Unknown')}", f"Max Sol: {manifest.get('max_sol', 'Unknown')}", f"Max Earth Date: {manifest.get('max_date', 'Unknown')}", f"Total Photos: {manifest.get('total_photos', 'Unknown')}", "nPhoto Summary per Sol (showing latest 5 sols with photos):" ] photos_per_sol = manifest.get('photos', []) # Sort by sol descending to show latest first photos_per_sol_sorted = sorted(photos_per_sol, key=lambda x: x.get('sol', -1), reverse=True) display_limit = 5 count = 0 for sol_info in photos_per_sol_sorted: if count >= display_limit: result.append(f"n... and {len(photos_per_sol) - display_limit} more sols with photos.") break result.append(f" Sol {sol_info.get('sol', 'N/A')}: {sol_info.get('total_photos', 0)} photos") result.append(f" Cameras: {', '.join(sol_info.get('cameras', []))}") count += 1 return "n".join(result) except Exception as e: logger.error(f"Error processing Mars Rover Manifest data: {str(e)}") return f"Error processing Mars Rover Manifest data: {str(e)}"
  • Helper dictionary defining valid Mars rovers and their camera types, used for input validation in the get_mars_rover_manifest and get_mars_rover_photos tools.
    ROVER_CAMERAS = { "curiosity": ["FHAZ", "RHAZ", "MAST", "CHEMCAM", "MAHLI", "MARDI", "NAVCAM"], "opportunity": ["FHAZ", "RHAZ", "NAVCAM", "PANCAM", "MINITES"], "spirit": ["FHAZ", "RHAZ", "NAVCAM", "PANCAM", "MINITES"] }
  • Shared helper function to make HTTP requests to NASA APIs, handle JSON/binary responses, errors, and API key inclusion. Used by get_mars_rover_manifest to fetch the manifest data.
    async def make_nasa_request(url: str, params: dict = None) -> Union[dict[str, Any], List[Any], None]: """Make a request to the NASA API with proper error handling. Handles both JSON and binary (image) responses. """ logger.info(f"Making request to: {url} with params: {params}") if params is None: params = {} # Ensure API key is included in parameters if "api_key" not in params: params["api_key"] = API_KEY async with httpx.AsyncClient() as client: try: response = await client.get(url, params=params, timeout=30.0, follow_redirects=True) response.raise_for_status() # Raise an exception for bad status codes (4xx or 5xx) content_type = response.headers.get("Content-Type", "").lower() if "application/json" in content_type: try: return response.json() except json.JSONDecodeError as json_err: logger.error(f"JSON decode error for URL {response.url}: {json_err}") logger.error(f"Response text: {response.text[:500]}") # Log beginning of text return {"error": "Failed to decode JSON response", "details": str(json_err)} elif content_type.startswith("image/"): logger.info(f"Received binary image content ({content_type}) from {response.url}") # Return a dictionary indicating binary content was received return { "binary_content": True, "content_type": content_type, "url": str(response.url) # Return the final URL after redirects } else: # Handle other unexpected content types logger.warning(f"Unexpected content type '{content_type}' received from {response.url}") return {"error": f"Unexpected content type: {content_type}", "content": response.text[:500]} except httpx.HTTPStatusError as http_err: logger.error(f"HTTP error occurred: {http_err} - {http_err.response.status_code} for URL {http_err.request.url}") try: # Try to get more details from response body if possible error_details = http_err.response.json() except Exception: error_details = http_err.response.text[:500] return {"error": f"HTTP error: {http_err.response.status_code}", "details": error_details} except httpx.RequestError as req_err: logger.error(f"Request error occurred: {req_err} for URL {req_err.request.url}") return {"error": "Request failed", "details": str(req_err)} except Exception as e: logger.error(f"An unexpected error occurred: {str(e)}") return {"error": "An unexpected error occurred", "details": str(e)}

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/AnCode666/nasa-mcp'

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