jpl_sentry
Access JPL Sentry data to assess Near-Earth Object impact risks, retrieve impact probabilities, and monitor potential Earth impactors through NASA's asteroid tracking system.
Instructions
JPL Sentry - NEO Earth impact risk assessment data
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of results to return | |
| date_min | No | Start date (YYYY-MM-DD) | |
| date_max | No | End date (YYYY-MM-DD) | |
| des | No | Object designation (e.g., '2011 AG5' or '29075') | |
| spk | No | Object SPK-ID | |
| h_max | No | Maximum absolute magnitude (size filter) | |
| ps_min | No | Minimum Palermo Scale value | |
| ip_min | No | Minimum impact probability | |
| removed | No | Get objects removed from Sentry monitoring | |
| all | No | Get all virtual impactors data |
Implementation Reference
- src/handlers/jpl/sentry.ts:13-109 (handler)The sentryHandler function implements the core execution logic for the 'jpl_sentry' tool. It queries the JPL Sentry API endpoint, transforms input parameters, handles different query modes (specific object by des/spk, removed objects, virtual impactors, summary), generates resource URIs, stores results as MCP resources, and returns formatted JSON content or error responses.export async function sentryHandler(args: Record<string, any>) { try { // Base URL for the Sentry API const baseUrl = 'https://ssd-api.jpl.nasa.gov/sentry.api'; // Transform parameter names from underscore to hyphenated format const transformedParams = transformParamsToHyphenated(args); // Make the API request const response = await axios.get(baseUrl, { params: transformedParams }); const data = response.data; // Create a resource URI that represents this query let resourceUri: string; let resourceName: string; if (args.des) { // Object mode - query for a specific object resourceUri = `jpl://sentry/object/${args.des}`; resourceName = `Impact risk assessment for object ${args.des}`; // Check if object is in the Sentry database or was removed if (data.error && data.error === "specified object removed") { resourceName += ` (removed on ${data.removed})`; } else if (data.error && data.error === "specified object not found") { resourceName += ` (not found)`; } else if (data.summary) { resourceName = `Impact risk assessment for ${data.summary.fullname}`; } } else if (args.spk) { // Object mode - query for a specific object by SPK-ID resourceUri = `jpl://sentry/object/${args.spk}`; resourceName = `Impact risk assessment for object SPK ${args.spk}`; // Update name if we have more info if (data.summary) { resourceName = `Impact risk assessment for ${data.summary.fullname}`; } } else if (args.removed === true || args.removed === '1' || args.removed === 'Y' || args.removed === 'true') { // Removed objects mode resourceUri = `jpl://sentry/removed`; resourceName = `Objects removed from Sentry impact monitoring`; } else if (args.all === true || args.all === '1' || args.all === 'Y' || args.all === 'true') { // Virtual impactors mode resourceUri = `jpl://sentry/vi`; // Add any constraints to the URI const constraints = Object.entries(args) .filter(([key]) => key !== 'all') .map(([key, value]) => `${key}=${value}`) .join('&'); if (constraints) { resourceUri += `?${constraints}`; } resourceName = `Sentry virtual impactors data`; } else { // Summary mode resourceUri = `jpl://sentry/summary`; // Add any constraints to the URI const constraints = Object.entries(args) .map(([key, value]) => `${key}=${value}`) .join('&'); if (constraints) { resourceUri += `?${constraints}`; } resourceName = `Sentry impact risk summary data`; } // 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 Sentry API: ${error.message}` }], isError: true }; } }
- src/index.ts:1182-1229 (schema)Defines the input schema and description for the 'jpl_sentry' tool in the tools/list response, specifying all supported parameters and their descriptions.name: "jpl_sentry", description: "JPL Sentry - NEO Earth impact risk assessment data", inputSchema: { type: "object", properties: { limit: { type: "number", description: "Maximum number of results to return" }, "date_min": { type: "string", description: "Start date (YYYY-MM-DD)" }, "date_max": { type: "string", description: "End date (YYYY-MM-DD)" }, "des": { type: "string", description: "Object designation (e.g., '2011 AG5' or '29075')" }, "spk": { type: "string", description: "Object SPK-ID" }, "h_max": { type: "number", description: "Maximum absolute magnitude (size filter)" }, "ps_min": { type: "string", description: "Minimum Palermo Scale value" }, "ip_min": { type: "string", description: "Minimum impact probability" }, "removed": { type: "boolean", description: "Get objects removed from Sentry monitoring" }, "all": { type: "boolean", description: "Get all virtual impactors data" } } } },
- src/index.ts:527-531 (registration)Registers the 'jpl_sentry' tool in the tools/manifest API response with its name, id, and description.{ name: "jpl_sentry", id: "jpl/sentry", description: "JPL Sentry - NEO Earth impact risk assessment data" },
- src/index.ts:1896-1932 (registration)The dynamic dispatch logic in handleToolCall that imports and executes the sentry handler for 'jpl/sentry' tools via dynamic import of './handlers/jpl/sentry.js' and calls the default exported function.} else if (internalToolId.startsWith("jpl/")) { // 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/handlers/jpl/sentry.ts:112-112 (helper)Default export enabling dynamic import in the central handleToolCall dispatcher.export default sentryHandler;