Skip to main content
Glama

nasa_cmr

Search NASA's Common Metadata Repository to access data collections using keywords, pagination, and sorting options for precise results. Ideal for retrieving satellite imagery, Mars Rover photos, and space weather data.

Instructions

NASA Common Metadata Repository - search for NASA data collections

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
keywordYesSearch keyword
limitNoMaximum number of results to return
pageNoPage number for pagination
sort_keyNoField to sort results by

Implementation Reference

  • Main execution logic for 'nasa_cmr' tool. Parses params, constructs CMR API query with support for spatial (polygon, bbox, point, line, circle), temporal, keyword, and pagination filters. Fetches data from https://cmr.earthdata.nasa.gov/search, processes response, registers results as MCP resources, returns structured content.
    export async function nasaCmrHandler(params: CmrParams) { try { const { search_type, format, limit, page, offset, sort_key, include_facets, polygon, bbox, point, line, circle, temporal, ...otherParams } = params; // Determine the correct format extension for the URL let formatExtension = format; if (format === 'json') { formatExtension = 'json'; } else if (format === 'umm_json') { formatExtension = 'umm_json'; } // Determine search endpoint based on search type const endpoint = `/${search_type}.${formatExtension}`; // Construct parameters const queryParams: Record<string, any> = { page_size: limit, page_num: page, offset, sort_key }; // Add other parameters for (const [key, value] of Object.entries(otherParams)) { if (value !== undefined) { queryParams[key] = value; } } // Add temporal parameter if provided if (temporal) { queryParams.temporal = temporal; } // Add spatial parameters if provided if (polygon) queryParams.polygon = polygon; if (bbox) queryParams.bbox = bbox; if (point) queryParams.point = point; if (line) queryParams.line = line; if (circle) queryParams.circle = circle; // Add facet options if requested if (include_facets) { queryParams.include_facets = 'v2'; } // Make the request to CMR directly const response = await axios({ url: `${CMR_API_BASE_URL}${endpoint}`, params: queryParams, headers: { 'Client-Id': 'NASA-MCP-Server', 'Accept': format === 'json' || format === 'umm_json' ? 'application/json' : undefined }, timeout: 30000 // 30 second timeout }); // Parse the response based on format let data; if (format === 'json' || format === 'umm_json') { data = response.data; } else { // For non-JSON formats, just return the raw text data = { raw: response.data, format: format }; } // Format the response to match MCP expectations let summary = ''; let formattedData; if (search_type === 'collections') { const collectionsCount = format === 'json' ? (data.feed?.entry?.length || 0) : format === 'umm_json' ? (data.items?.length || 0) : 0; summary = `Found ${collectionsCount} NASA collections`; formattedData = data; } else { const granulesCount = format === 'json' ? (data.feed?.entry?.length || 0) : format === 'umm_json' ? (data.items?.length || 0) : 0; summary = `Found ${granulesCount} data granules`; formattedData = data; } // Create a resource ID const resourceParams = []; if (params.keyword) resourceParams.push(`keyword=${encodeURIComponent(params.keyword)}`); if (params.concept_id) resourceParams.push(`concept_id=${params.concept_id}`); if (temporal) resourceParams.push(`temporal=${encodeURIComponent(temporal)}`); const resourceId = `nasa://cmr/${search_type}${resourceParams.length > 0 ? '?' + resourceParams.join('&') : ''}`; // Register the response as a resource addResource(resourceId, { name: `NASA CMR ${search_type} search${params.keyword ? ` for "${params.keyword}"` : ''}`, mimeType: 'application/json', text: JSON.stringify(formattedData, null, 2) }); // If the response includes specific collections or granules, register those too if (formattedData.feed?.entry && Array.isArray(formattedData.feed.entry)) { formattedData.feed.entry.forEach((entry: any, index: number) => { if (index < 5) { // Limit to first 5 entries to avoid too many resources const entryId = entry.id || entry['concept-id'] || `${search_type}-${index}`; const entryTitle = entry.title || `NASA ${search_type} Item ${index + 1}`; const entryResourceId = `nasa://cmr/${search_type}/item?id=${entryId}`; addResource(entryResourceId, { name: entryTitle, mimeType: 'application/json', text: JSON.stringify(entry, null, 2) }); } }); } return { content: [ { type: "text", text: summary }, { type: "text", text: JSON.stringify(formattedData, null, 2) } ], isError: false }; } catch (error: any) { console.error('Error in CMR handler:', error); // Proper error handling with isError flag return { isError: true, content: [{ type: "text", text: `Error searching NASA Common Metadata Repository: ${error.message || 'Unknown error'}` }] }; } }
  • Zod input validation schema for nasa_cmr tool parameters, defining all supported CMR search options including search_type, keywords, spatial geometries, temporal ranges, pagination, and output format.
    export const cmrParamsSchema = z.object({ // Search type - collections or granules search_type: z.enum(['collections', 'granules']).default('collections'), // Basic search parameters keyword: z.string().optional(), concept_id: z.string().optional(), entry_title: z.string().optional(), short_name: z.string().optional(), provider: z.string().optional(), // Temporal parameters temporal: z.string().optional().describe('Temporal range in the format: start_date,end_date'), // Spatial parameters polygon: polygonSchema.optional(), bbox: bboxSchema.optional(), point: pointSchema.optional(), line: lineSchema.optional(), circle: circleSchema.optional(), // Platform, instrument, and project platform: z.string().optional(), instrument: z.string().optional(), project: z.string().optional(), // Processing level and data format processing_level_id: z.string().optional(), granule_data_format: z.string().optional(), // Search flags downloadable: z.boolean().optional(), browsable: z.boolean().optional(), online_only: z.boolean().optional(), // Facet parameters include_facets: z.boolean().optional(), // Pagination and sorting limit: z.number().optional().default(10), page: z.number().optional().default(1), offset: z.number().optional(), sort_key: z.string().optional(), // Result format format: z.enum(['json', 'umm_json', 'atom', 'echo10', 'iso19115', 'iso_smap', 'kml']).optional().default('json') });
  • src/index.ts:1558-1574 (registration)
    MCP server request handler registration for direct 'nasa/cmr' method calls, validating params with Zod and delegating to central handleToolCall dispatcher.
    // CMR Handler server.setRequestHandler( z.object({ method: z.literal("nasa/cmr"), params: z.object({ keyword: z.string().optional(), search_type: z.enum(['collections', 'granules']).optional(), format: z.enum(['json', 'umm_json', 'atom', 'echo10', 'iso19115', 'iso_smap', 'kml']).optional(), limit: z.number().optional(), page: z.number().optional(), sort_key: z.string().optional() }).passthrough().optional() }), async (request) => { return await handleToolCall("nasa/cmr", request.params || {}); } );
  • src/index.ts:793-829 (registration)
    Tool metadata registration in static 'tools/list' response, defining 'nasa_cmr' name, description, and detailed JSON Schema for inputs.
    name: "nasa_cmr", description: "NASA Common Metadata Repository - search for NASA data collections", inputSchema: { type: "object", properties: { keyword: { type: "string", description: "Search keyword" }, search_type: { type: "string", description: "Search type (collections or granules)", enum: ["collections", "granules"], default: "collections" }, format: { type: "string", description: "Response format", enum: ["json", "umm_json", "atom", "echo10", "iso19115", "iso_smap", "kml"], default: "json" }, limit: { type: "number", description: "Maximum number of results to return" }, page: { type: "number", description: "Page number for pagination" }, sort_key: { type: "string", description: "Field to sort results by" } }, required: ["keyword","search_type", "format"] } },
  • src/index.ts:463-466 (registration)
    Tool listing in 'tools/manifest' response, declaring 'nasa_cmr' tool with ID and description.
    name: "nasa_cmr", id: "nasa/cmr", description: "Search NASA's Common Metadata Repository for satellite data" },

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