Skip to main content
Glama

browse_asteroids

Explore and analyze NASA's asteroid dataset by querying detailed information about asteroids, enabling insights into their characteristics and trajectories directly from compatible AI clients.

Instructions

Browse the asteroid dataset.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • The main handler function for the 'browse_asteroids' tool. It calls the NASA NEO browse API, processes the JSON response, and returns a formatted string summary of the first 10 near-Earth objects, including page info.
    async def browse_asteroids() -> str: """Browse the asteroid dataset.""" url = f"{NASA_API_BASE}/neo/rest/v1/neo/browse" data = await make_nasa_request(url) if not data: return "Could not retrieve asteroid dataset 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 Browse Asteroids API. URL: {data.get('url')}" try: near_earth_objects = data.get('near_earth_objects', []) page_info = f"Page {data.get('page', {}).get('number', 'Unknown')} of {data.get('page', {}).get('total_pages', 'Unknown')}" total_elements = f"Total elements: {data.get('page', {}).get('total_elements', 'Unknown')}" result = [page_info, total_elements, ""] # Limit the number of asteroids displayed to avoid excessive output display_limit = 10 count = 0 for asteroid in near_earth_objects: if count >= display_limit: result.append(f"n... and {len(near_earth_objects) - display_limit} more asteroids on this page.") break result.append(f"ID: {asteroid.get('id', 'Unknown')}") result.append(f"Name: {asteroid.get('name', 'Unknown')}") result.append(f"Absolute magnitude: {asteroid.get('absolute_magnitude_h', 'Unknown')}") result.append(f"Estimated diameter (min): {asteroid.get('estimated_diameter', {}).get('kilometers', {}).get('estimated_diameter_min', 'Unknown')} km") result.append(f"Estimated diameter (max): {asteroid.get('estimated_diameter', {}).get('kilometers', {}).get('estimated_diameter_max', 'Unknown')} km") result.append(f"Potentially hazardous: {'Yes' if asteroid.get('is_potentially_hazardous_asteroid', False) else 'No'}") result.append("-" * 40) count += 1 return "n".join(result) except Exception as e: logger.error(f"Error processing Browse Asteroids data: {str(e)}") return f"Error processing asteroid data: {str(e)}"
  • Shared helper function used by browse_asteroids (and other tools) to make HTTP requests to NASA APIs, handle JSON/binary responses, errors, and add API key.
    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)}
  • The @mcp.tool() decorator registers the browse_asteroids function as an MCP tool.
    async def browse_asteroids() -> str:

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