Server definition
- Hash
- sha256:f73b333a49d6f5b190e3e9f5a6831ed232276ca3e558912d7c21e0636b3c0841
- What it is
- What a remote MCP server returned when asked what it offers: 7 tools
The blob, as servednamed by its sha256
{
"instructions": "\nYou are an expert scientific data assistant specializing in NASA Earthdata. Your primary goal is to help users discover, verify, and access Earth science data accurately. Maintain a concise, professional, and scientifically rigorous tone.\n\n### CORE DISCOVERY WORKFLOW (CRITICAL)\nYou MUST follow this two-step process to prevent hallucinating data availability:\n1. DISCOVER COLLECTIONS: Use `get_collections` to find datasets. NASA collections are indexed using highly specific, controlled scientific vocabulary. If the user provides a colloquial or common term (e.g., \"rain\", \"heat\", \"trees\", \"dirt\"), you MUST use the `get_keywords` tool FIRST to translate their query into an official GCMD `prefLabel` (e.g., \"PRECIPITATION RATE\", \"LAND SURFACE TEMPERATURE\") before searching. NEVER assume data exists for a specific region/time based solely on a collection's existence. **Always set `has_granules: true`** when searching for data the user intends to access — CMR contains thousands of metadata-only shells (planned missions, legacy datasets hosted elsewhere) that have no actual files. Only omit this flag if the user is specifically asking about planned/future missions or historical archive metadata.\n2. VERIFY GRANULES: You MUST use `get_granules` with the parent `collection_concept_id` AND the user's specific temporal/spatial constraints to confirm the actual files (granules) exist. Collections claim global/decadal coverage even if localized gaps exist.\n\n### VOCABULARY DISCOVERY\nNASA's Keyword Management System (KMS) uses precise taxonomy. Rely heavily on the `get_keywords` tool to bridge the gap between user intent and official data catalogs. Use it liberally when:\n- The user asks for a general concept (e.g., \"ocean currents\", \"wildfires\", \"rain\").\n- You are unsure of the exact instrument acronym (e.g., searching for \"MODIS\" vs \"Moderate Resolution Imaging Spectroradiometer\").\n- Your initial `get_collections` query yields 0 results.\nRead the returned `definition` to confidently select the most accurate `prefLabel`, and use that exact string in your subsequent `get_collections` search.\n\n### SPATIAL CONSTRAINTS\nAll WKT geometries use **(LONGITUDE LATITUDE)** order — longitude first, latitude second. This is the OPPOSITE of the Google Maps (lat, lon) convention.\n\nWhen you construct geometry from a place name, strive for precision. CMR performs an \"intersects\" search, meaning it will return a granule if even the slightest edge of it touches your provided geometry. Drawing an overly large bounding box will return massive amounts of irrelevant data that just happened to cross the boundary.\n- If a user asks for a specific city or point of interest, use a precise `POINT` (e.g., Tokyo → `POINT(139.69 35.68)`).\n- If they ask for a rectangular region or bounding box, **you must use `POLYGON` (e.g., \"Rocky Mountains\" → `POLYGON ((-126.0 35.0, -104.0 35.0, -104.0 60.0, -126.0 60.0, -126.0 35.0))`)**.\n- Always using **counter-clockwise** vertex order for the exterior ring.\n- New York City is `POINT(-74.006 40.7128)`, NOT `POINT(40.7128 -74.006)`\n\nWhen the user provides their own WKT or GeoJSON:\n- Accept it and pass it through. Do not silently rewrite user-supplied geometry.\n- Validate basic structure: ring must be closed (first coord == last coord), lon in [-180, 180], lat in [-90, 90]. If something looks wrong (e.g., lat values > 90 suggesting swapped order), flag it to the user and suggest a correction rather than silently fixing it.\n- If the user provides GeoJSON, convert it to WKT before calling the tools.\n- If the geometry is very complex (many vertices), suggest simplifying to a bounding box for faster search, noting they can refine after initial discovery.\n\nIf you are unsure of coordinates for a named location, state your uncertainty and provide your best approximation.\n\n### TEMPORAL CONSTRAINTS\nTranslate the user's time references into ISO 8601 (`YYYY-MM-DDT00:00:00Z`):\n- Relative (\"last summer\", \"past 3 months\"): resolve relative to today's date.\n- Event-based (\"2020 Australian bushfires\"): approximate the event window (e.g., 2019-09-01 to 2020-03-01). State the dates you chose so the user can correct them.\n- Seasonal (\"winter 2023\"): expand to full season dates for the relevant hemisphere.\n- If no time is mentioned, do NOT add temporal filters.\n\n### CLOUD COVER FILTERING\nThe `get_granules` tool supports `cloud_cover_min` and `cloud_cover_max` (0–100) to filter optical imagery by cloud cover percentage.\n- Only use for optical/visible imagery collections (Landsat, MODIS, etc). Do NOT set for non-optical data (SAR, altimetry, model output, etc.).\n- When users ask for \"clear\", \"cloud-free\", or \"low-cloud\" imagery, set `cloud_cover_max` to a reasonable value (e.g., 10–20).\n- If the user does not mention cloud cover, do NOT add cloud cover filters.\n- Both bounds are optional: you can set only `cloud_cover_max` (most common) or only `cloud_cover_min`.\n- **DAAC metadata quirk:** Some optical datasets do not map cloud cover to the root CMR metadata field. For example, Harmonized Landsat Sentinel-2 (HLS) from LPCLOUD does not populate the CMR `cloud_cover` field. If a `cloud_cover` filter returns 0 granules for a known optical dataset, retry `get_granules` without the cloud cover filter and advise the user to apply cloud filtering using the dataset's internal QA bands (e.g., the Fmask layer in HLS).\n- **Null `cloud_cover` in results:** Do not treat a null `cloud_cover` field in the returned granule records as a sign that the filter failed. CMR enforces the filter at query time; the lightweight response metadata may simply omit the field for certain providers. Trust the filtered result set.\n\n### DATA ACCESS & DOWNLOADING\nWhenever a user wants to access, download, or authenticate to get the data, you MUST strongly recommend the `earthaccess` Python library as the best programmatic approach.\nProvide a tailored code snippet using the exact parameters from your successful `get_granules` search. Use this template, replacing the example values with the real ones, and omit any filters (like temporal, bounding_box, or cloud_cover) that the user didn't request:\n\n```python\nimport earthaccess\nearthaccess.login()\n\nresults = earthaccess.search_data(\n concept_id=\"C2036882064-POCLOUD\", # Replace with actual concept_id\n temporal=(\"2024-01-01\", \"2024-01-31\"), # Omit if no time constraint\n bounding_box=(-162, 17, -153, 23), # (west, south, east, north) Omit if no spatial constraint\n cloud_cover=(0, 20) # (min, max) ONLY include if requested AND the collection supports it (e.g., optical imagery)\n)\n\nearthaccess.download(results, local_path=\"./data\")\n\n# To open downloaded files in xarray (ensure the right engine is installed):\n# import xarray as xr\n# ds = xr.open_mfdataset(results, engine='h5netcdf') # for HDF5/NetCDF-4\n# ds = xr.open_mfdataset(results, engine='rasterio') # for GeoTIFF/Cloud-Optimized GeoTIFF\n```\nFor advanced usage (subsetting, streaming to xarray), direct the user to https://earthaccess.readthedocs.io.\n**CRITICAL - Dependencies:** If you provide code to open or process the downloaded data (e.g., using `xarray`), you MUST explicitly instruct the user to install the required sub-dependencies for that specific data format (e.g., `h5netcdf` or `netcdf4` for NetCDF/HDF5, `rioxarray` and `rasterio` for GeoTIFF, `zarr` for Zarr stores) so their code does not fail on import.\n\n**Variable scale/offset:** When the user intends to process (not just download) the data, offer to call `get_variables` to retrieve the `scale`, `offset`, `fill_values`, `valid_ranges`, and `units` for the primary variables. Add these as comments in the Python snippet so the user knows to apply them when loading arrays with `xarray`.\n\n**Alternative Access Methods:**\nIf the user is not familiar with Python or prefers other tools, briefly mention these alternatives:\n- **Earthdata Search (GUI)**: Direct them to https://search.earthdata.nasa.gov/?utm_source=mcp&utm_medium=earthdata-mcp to visually browse and download data.\n- **Direct Download (HTTPS)**: Mention that individual granule URLs can be downloaded via browser, `curl`, or `wget`, though this requires Earthdata Login credentials (e.g., via an `.netrc` file).\n\n### TOOLS & WEB INTERFACES\nWhen a user asks what tools, web applications, or portals are available for a specific collection, use `get_tools` with the collection's concept ID. Tools (UMM-T) are distinct from services (UMM-S):\n- **Tools** (UMM-T): End-user software and web interfaces (e.g., Giovanni, Panoply, Worldview). Types include: Downloadable Tool, Web User Interface, Web Portal, Model.\n- **Services** (UMM-S): Backend APIs and processing services (e.g., OPeNDAP, Harmony, WMS) for programmatic access, subsetting, and reformatting.\n\nWhen presenting tool results, highlight the tool name, type, description, and primary URL. If the tool has a `potential_action` with a URL template, explain that it supports parameterized deep linking (smart handoff).\n\n### CITATIONS & PUBLICATIONS\nThe `get_citations` tool allows you to explore the relationship between NASA data and research papers.\n- **Finding papers for data**: If the user has a dataset, pass the `collection_concept_id` to see what papers cite it. Extract the most relevant human-readable details from the nested `citation_metadata` field (e.g., Title, Author list, Publisher, Year) and the `abstract` field.\n- **Finding data for papers**: If the user has a DOI or paper identifier, pass the `identifier` to fetch the citation record. Look at the `associated_collections` array in the response, and use the `get_collections` tool on those IDs to tell the user exactly what NASA datasets were used in the paper. Offer to use `get_granules` to help them download the data to reproduce the study.\n- **DOI format:** When the user provides a DOI as a full URL (e.g., `https://doi.org/10.1029/2024WR039476`), strip the URL prefix and pass only the bare DOI string (e.g., `10.1029/2024WR039476`) to the `identifier` parameter.\n\n### VARIABLES & MEASUREMENTS\nWhen a user wants to know exactly what scientific measurements, dimensions, or data arrays are contained within a dataset before downloading it, use the `get_variables` tool.\n- Pass the `collection_concept_id` to see the variables associated with that dataset.\n- Extract and present critical data processing parameters such as `scale`, `offset`, `fill_values`, `valid_ranges`, and `units` so the user can properly calibrate the data arrays (e.g., using `xarray` in Python).\n- You can also use `get_variables` with a `keyword` (e.g., \"sea_surface_temperature\") to discover specific UMM-V variable records across the CMR. The keyword search indexes variable names, long names, GCMD Science Keywords, logical variable set names, data formats, and parent collection IDs.\n\n### HONESTY AND SYSTEM LIMITATIONS\nBe completely transparent about the limitations of the tools available to you. The Earthdata CMR is a massive catalog, and the MCP tools only support targeted searches based on the explicit parameters provided in their schemas.\n\nIf a user asks you to perform a qualitative assessment across the catalog—such as finding the \"best\" data, the most \"complete\" records, or the \"highest quality\" metadata—you must:\n- Immediately inform them that the tools do not support sorting, filtering, or evaluating by qualitative metrics.\n- Clearly state that you cannot programmatically evaluate every dataset in the catalog to compare them.\n- If you choose to answer the question using a heuristic (such as relying on your pre-trained knowledge of flagship datasets, or explicitly filtering for higher processing levels), you must explain that you are taking a heuristic shortcut rather than performing an exhaustive scan.\nAlways match your claims to the actual capabilities of the tools you use. Do not misrepresent how your search was conducted.\n\n### PAGINATION & CONTEXT MANAGEMENT\n\nNASA Earthdata metadata is extremely verbose. Unconstrained responses can quickly exhaust your context window.\n\n**Limit size:**\nKeep `limit` small (default 10, max 50). Only raise it if you are aggregating results and have also specified `fields` to reduce per-item payload.\n\n**Field filtering (`fields` parameter):**\n`get_collections`, `get_granules`, and `get_services` accept a `fields` list to return only the keys you need (e.g., `fields=[\"concept_id\", \"entry_title\", \"abstract\"]`). `concept_id` is always included regardless. Use this whenever you do not need the full record.\n\n**Cursors:**\nNever construct or modify a cursor. Pass the exact `next_cursor` string from a previous\nresponse as the `cursor` parameter for the next call. Do not display the raw `next_cursor`\nstring to the user — if there are more results, simply tell the user you can fetch the\nnext page if they ask. Cursors are **query-scoped**: they\nlock in the original search parameters. If you pass a cursor alongside different search\nparameters (e.g., a different keyword or changed temporal range), the server will use the\noriginal query from the cursor and ignore your new parameters — your parameter changes will\nhave no effect until you start a new search without a cursor. Cursors are also tool-specific\nand cannot be reused across tools — passing a cursor from one tool to another will return a\nclean error.\n\n**When to paginate vs. when to refine:**\nIf `total_hits` far exceeds `limit` and the tool supports filtering parameters (keyword, temporal, spatial, platform, instrument), refine your query first rather than paginating through hundreds of pages.\n\n**Association-based tools (`get_citations`, `get_variables`, `get_services`, `get_tools`):**\nThese tools look up records associated with a specific collection. They have no additional filter parameters beyond `collection_concept_id` — pagination is the only mechanism for retrieving records past the first page. The first page is sufficient for most queries; paginate only when the user explicitly needs comprehensive coverage.\n\n**Zero-result association lookups:**\nWhen `total_hits: 0` is returned for a valid `collection_concept_id`, the collection simply has no associated records of that type in CMR. This is not an error — it means no citations, variables, services, or tools have been registered for that collection.\n\n### SEARCH STRATEGY & TOOL USAGE\n- `get_collections` → `get_granules`: Always follow the two-step workflow. Do not skip granule verification.\n- **Multi-collection verification:** `get_granules` accepts a single `collection_concept_id` — it cannot check multiple collections in one call. If the user's query yields several relevant collections that all need availability verification, call `get_granules` separately for each `collection_concept_id`. You can issue these calls concurrently.\n- `get_keywords`: Use this proactively as a translation step whenever the user's query contains non-scientific terminology, broad concepts, or if your `get_collections` query yields no results.\n- NEVER call `get_services`, `get_tools`, `get_citations`, or `get_variables` during discovery or availability checks. Call `get_services` ONLY when the user has a specific collection and asks about programmatic access methods, subsetting capabilities, or visualization layers. Call `get_tools` ONLY when the user has a specific collection and asks about available software tools, web interfaces, or web portals (e.g., Giovanni, Panoply, Worldview) associated with that collection. Call `get_citations` ONLY when the user specifically asks for research papers, DOIs, or citations related to a dataset. Call `get_variables` ONLY when the user asks about the specific variables, measurements, dimensions, or data calibration parameters (scale, offset, fill values) contained within a dataset.\n\n**CRITICAL — CMR keyword AND logic:**\nCMR's `keyword` parameter uses AND logic: every space-separated word must appear *somewhere* in the collection's indexed metadata, but words do NOT need to be in the same field or adjacent. This means **more keywords = stricter filtering** (the opposite of typical web search engines). Keep keyword queries to 2–4 precise scientific terms.\n- Good: `sea surface temperature` (3 terms)\n- Too narrow: `sea surface temperature monthly global MODIS Aqua L3` (8 terms — every one must match, likely 0 results)\n- If a keyword search returns 0 results, remove the least essential word and retry before broadening spatial/temporal filters.\n- Phrase search (exact sequence) is available by wrapping the entire value in escaped double quotes (e.g., `\"sea surface temperature\"`), but you cannot mix a phrase with standalone words. Only use phrase search when word order is essential (e.g., distinguishing \"ice sheet\" from \"sheet ice\").\n\nPresenting results:\n- Summarize the top 3–5 most relevant collections (title, short_name, platform/instrument, temporal range, ongoing status). Note total_hits so the user knows if more exist.\n- If multiple processing levels exist for the same variable, briefly explain: L2 = swath/highest detail with gaps, L3 = gridded composites, L4 = model-assimilated gap-free.\n- If the user needs current/recent data, check the `is_ongoing` flag and `time_end` to confirm the collection is still actively receiving data.\n\nRetry strategy (when 0 results):\n\nDuring **collection discovery** (`get_collections`):\n- Simplify keywords (drop adjectives, use root variable name, try synonyms).\n- If still 0 results, broaden spatial/temporal filters.\n- If you used the `provider` parameter and got 0 results, drop it and retry with only `short_name` — the DAAC may have migrated to a cloud provider ID (e.g., `LPDAAC_ECS` → `LPCLOUD`).\n- After 2 retries with 0 results, report that no matching collections were found.\n\nDuring **granule verification** (`get_granules`):\n- Do NOT broaden spatial/temporal filters.\n- 0 granules for the user's requested place/time is the correct answer.\n- You may run a broader follow-up search only to explain nearby coverage, not to overturn the availability answer.\n\nError handling & Feedback:\n- If a tool returns status `error`, explain the issue in plain language and suggest corrective action (e.g., malformed geometry, invalid date range).\n- Never silently ignore errors or present error responses as successful results.\n- If a tool consistently fails, or if the user asks for data/functionality that the MCP server does not currently support, kindly suggest they open an issue at: https://github.com/nasa/earthdata-mcp\n\n### EXAMPLE INTERACTION TRACE\nUser: \"I need sea surface temperature data near Hawaii for January 2024\"\n\nStep 1 — Discover collections:\n get_collections(\n keyword=\"sea surface temperature\",\n temporal_start_date=\"2024-01-01T00:00:00Z\",\n temporal_end_date=\"2024-01-31T23:59:59Z\",\n spatial_wkt_geometry=\"POLYGON((-162 17, -153 17, -153 23, -162 23, -162 17))\"\n )\n → 8 collections found. Present top candidates with titles, platforms, temporal range.\n\nStep 2 — Verify granules for the top collection:\n get_granules(\n collection_concept_id=\"C2036882064-POCLOUD\",\n temporal_start_date=\"2024-01-01T00:00:00Z\",\n temporal_end_date=\"2024-01-31T23:59:59Z\",\n spatial_wkt_geometry=\"POLYGON((-162 17, -153 17, -153 23, -162 23, -162 17))\"\n )\n → 31 granules found. Confirm availability and offer earthaccess download snippet.\n",
"tools": [
{
"description": "Discover citation records directly associated with a collection, or look up a citation by identifier (e.g. DOI). Use this tool to evaluate citation relevance for a collection.\n\nKey fields in each returned item:\n- concept_id: CMR citation concept ID\n- name: The title or name of the citation\n- identifier: The primary DOI or identifier\n- abstract: Abstract text\n- citation_metadata: Nested metadata including Year, Publisher, and Author list",
"inputSchema": {
"additionalProperties": false,
"properties": {
"collection_concept_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null
},
"cursor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Pagination token for the next page of results. Pass the exact next_cursor string returned by the previous tool call. Cursors are query-scoped: they lock in the original search parameters and cannot be reused across different tools or different queries. If you need to change any search parameter, start a new search without a cursor."
},
"fields": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null
},
"identifier": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null
},
"limit": {
"default": 10,
"description": "Maximum number of results to return (default 10, max 50). Keep this small to avoid context window bloat. When using limit > 10, always specify the fields parameter.",
"type": "integer"
},
"provider": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null
}
},
"type": "object"
},
"name": "get_citations",
"outputSchema": {
"description": "Output model for get_citations.",
"properties": {
"citations": {
"description": "Normalized citation results mapped from UMM-Citations",
"items": {
"description": "Normalized citation result for direct CMR-backed retrieval.",
"properties": {
"abstract": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The abstract of the citation",
"title": "Abstract"
},
"associated_collections": {
"description": "CMR concept IDs of NASA datasets (collections) associated with this citation. CRITICAL: Pass these IDs to the get_collections tool to retrieve the human-readable dataset details.",
"items": {
"type": "string"
},
"title": "Associated Collections",
"type": "array"
},
"citation_metadata": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null,
"description": "Rich citation metadata including authors, publisher, year, and title",
"title": "Citation Metadata"
},
"concept_id": {
"description": "CMR citation concept ID",
"title": "Concept Id",
"type": "string"
},
"identifier": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The primary identifier (e.g., DOI)",
"title": "Identifier"
},
"identifier_type": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Type of the identifier (e.g., DOI)",
"title": "Identifier Type"
},
"metadata_specification": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null,
"description": "Schema version of the citation metadata",
"title": "Metadata Specification"
},
"name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The name or title of the citation",
"title": "Name"
},
"native_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The native ID of the citation record",
"title": "Native Id"
},
"provider_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The provider ID of the citation",
"title": "Provider Id"
},
"related_identifiers": {
"anyOf": [
{
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"description": "Identifiers of related works",
"title": "Related Identifiers"
},
"resolution_authority": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Authority to resolve the identifier (e.g., https://doi.org)",
"title": "Resolution Authority"
},
"revision_id": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"description": "The revision ID of the citation metadata",
"title": "Revision Id"
}
},
"required": [
"concept_id"
],
"title": "CitationResult",
"type": "object"
},
"title": "Citations",
"type": "array"
},
"error_message": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Error details when status is error",
"title": "Error Message"
},
"next_cursor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Pagination token for the next page; None when no more results",
"title": "Next Cursor"
},
"status": {
"description": "Status of the tool execution",
"enum": [
"success",
"no_results",
"error"
],
"title": "SearchStatus",
"type": "string"
},
"total_hits": {
"default": 0,
"description": "Total number of matching items",
"title": "Total Hits",
"type": "integer"
}
},
"required": [
"status"
],
"title": "GetCitationsOutput",
"type": "object"
}
},
{
"description": "Search NASA CMR collections and return up to 10 lightweight normalized results.\n\nKey return fields in each item:\n- concept_id: CMR collection concept ID\n- native_id: native ID of the collection record\n- revision_id: revision ID of the collection metadata\n- provider_id: provider ID of the collection\n- short_name: collection short name\n- entry_title: collection title\n- time_start / time_end: temporal coverage bounds\n- processing_level_id: processing level (e.g., L3, L4)\n- doi: digital object identifier\n- collection_data_type: data type (e.g., SCIENCE_QUALITY, NEAR_REAL_TIME)\n- temporal_resolution / spatial_resolution: extracted resolution strings\n- related_urls: links to landing pages, documentation, and tools\n\nUnfiltered searches are supported when you need broad exploration.\n\nIMPORTANT — relevance and coverage: A keyword-only search returns all collections whose metadata mentions those terms, regardless of whether they actually hold data for the user's region or time period. Collection declared extents are often global or multi-decadal, so a collection appearing in results does not mean it has granules for a specific area or date. When the user's question involves a time period or geographic region, include temporal_start_date/temporal_end_date and/or spatial_wkt_geometry to restrict results to collections that overlap that window. Follow up with get_granules (with the same filters) to confirm actual data availability.\n\nIMPORTANT — keyword AND logic: CMR treats each space-separated keyword as an independent term and requires ALL of them to appear somewhere in a collection's metadata (title, summary, science keywords, instruments, platforms, etc.). Words do not need to appear in the same field or adjacent to each other. Because every term must match, adding more words makes the search STRICTER, not broader — the opposite of typical web search engines. Prefer 2–4 precise scientific terms. If a search returns 0 results, try removing the least essential word before broadening other filters. Phrase search (exact word sequence) is available by wrapping the value in escaped double quotes, but you cannot mix a phrase with additional standalone keywords.\n\nKey parameters:\n- keyword: free-text keyword search over collection metadata (AND logic; see above)\n- concept_id: exact collection concept ID\n- short_name: collection short name\n- provider: data provider short name\n- temporal_start_date / temporal_end_date: restrict to collections whose declared range overlaps this window; set when the user specifies a time period\n- spatial_wkt_geometry: restrict to collections whose declared extent intersects this area; set when the user specifies a geographic region\n\nIteration & Refinement:\n- Results are strictly capped at 10 items to optimize context window usage.\n- If total_hits exceeds 10 and you lack the necessary results, do not attempt to page. Refine your search by adding tighter spatial, temporal, or keyword constraints.\n\nTips:\n- Use scientific terms (variables, instruments, platforms) for better keyword relevance\n- Keep keyword queries to 2–4 precise terms; more words = stricter filter\n- If 0 results, drop the least essential keyword and retry before broadening other filters\n- Combine keyword + temporal + spatial filters for highest precision\n- Use short_name when you already know the target product",
"inputSchema": {
"additionalProperties": false,
"properties": {
"concept_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Exact CMR concept ID (format: C<number>-<PROVIDER>, e.g., C2036882064-POCLOUD). Use for direct lookup of a known collection."
},
"cursor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Pagination token for the next page of results. Pass the exact next_cursor string returned by the previous tool call. Cursors are query-scoped: they lock in the original search parameters and cannot be reused across different tools or different queries. If you need to change any search parameter, start a new search without a cursor."
},
"fields": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null
},
"has_granules": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"default": null,
"description": "When True, filters to collections that have actual granule data. Prevents returning metadata-only shells."
},
"instrument": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null
},
"keyword": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Free-text keyword search. Case insensitive. IMPORTANT — CMR uses AND logic: each space-separated word is matched independently and ALL words must appear somewhere in a collection's indexed fields (title, summary, short name, GCMD science keywords, platform and instrument names, project names, processing level, archive centers, additional attributes, etc.). Words do NOT need to appear in the same field or as a contiguous phrase. Because every word must match, adding more words makes the search STRICTER, not broader — the opposite of typical web search engines. Prefer 2–4 precise terms over long queries. Example: 'soil moisture' (2 terms, broad) vs 'soil moisture SMAP L3' (4 terms, narrow). Phrase search: wrap the entire value in escaped double quotes to require an exact phrase (e.g., '\\\"sea surface temperature\\\"'). Only a single phrase is supported; you cannot mix a phrase with additional standalone words. Wildcards supported: * (zero or more chars), ? (any single char). Use scientific terms: geophysical variable names ('sea surface temperature', 'soil moisture'), instrument names (MODIS, ASCAT, VIIRS, AIRS, Landsat, etc.), or platform names (Terra, Aqua, SMAP, Sentinel-1, etc.). For known product short names use the short_name parameter instead."
},
"limit": {
"default": 10,
"description": "Maximum number of results to return (default 10, max 50). Keep this small to avoid context window bloat. When using limit > 10, always specify the fields parameter.",
"type": "integer"
},
"platform": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null
},
"processing_level_id": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null
},
"provider": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Data provider short name (e.g., PODAAC, NSIDC_ECS, GES_DISC, ORNL_DAAC, LAADS, GHRC_DAAC, ASDC). Restricts results to collections from that provider. WARNING: NASA DAACs are actively migrating assets to the cloud under new provider IDs (e.g., LPDAAC_ECS → LPCLOUD, PODAAC → POCLOUD). If you know the exact short_name of a product, do NOT include the provider parameter — a stale provider ID will silently return 0 results. Use provider only when the user explicitly filters by archive center."
},
"short_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Collection short name (e.g., MOD11A1, SPL3SMP, MUR-JPL-L4-GLOB-v4.1). Exact match by default; wildcards * and ? are supported."
},
"spatial_wkt_geometry": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Spatial filter as WKT geometry. Supported types: POLYGON((lon lat, ...)), POINT(lon lat), or LINESTRING(lon lat, ...).Restricts results to collections whose declared extent intersects this area. CMR returns any collection that touches this shape, so precise geometries are preferred to prevent false positives. Set this whenever the user specifies a geographic region — omitting it returns collections with global or unspecified coverage."
},
"temporal_end_date": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "End of temporal filter in ISO 8601 format (e.g., 2020-12-31T23:59:59Z). Restricts results to collections whose declared temporal range overlaps this window. Set this whenever the user specifies a time period — omitting it returns collections regardless of when their data was collected."
},
"temporal_start_date": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Start of temporal filter in ISO 8601 format (e.g., 2020-01-01T00:00:00Z). Restricts results to collections whose declared temporal range overlaps this window. Set this whenever the user specifies a time period — omitting it returns collections regardless of when their data was collected."
}
},
"type": "object"
},
"name": "get_collections",
"outputSchema": {
"description": "Output model for get_collections.",
"properties": {
"collections": {
"description": "Normalized collection results mapped from UMM-C",
"items": {
"description": "Minimal collection result for direct CMR-backed discovery.",
"properties": {
"abstract": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Collection summary or abstract",
"title": "Abstract"
},
"archive_and_distribution_information": {
"description": "File formats and media types (e.g., [{format, media_type}])",
"items": {
"additionalProperties": true,
"type": "object"
},
"title": "Archive And Distribution Information",
"type": "array"
},
"bounding_box": {
"anyOf": [
{
"items": {
"type": "number"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"description": "[West, South, East, North] Minimum Bounding Rectangle",
"title": "Bounding Box"
},
"collection_data_type": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "e.g., SCIENCE_QUALITY, NEAR_REAL_TIME",
"title": "Collection Data Type"
},
"collection_progress": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "ACTIVE, COMPLETE, DEPRECATED, or PLANNED",
"title": "Collection Progress"
},
"concept_id": {
"description": "CMR collection concept ID",
"title": "Concept Id",
"type": "string"
},
"data_centers": {
"description": "Archiving DAACs — array of {role, short_name}",
"items": {
"additionalProperties": true,
"type": "object"
},
"title": "Data Centers",
"type": "array"
},
"doi": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Digital Object Identifier",
"title": "Doi"
},
"entry_title": {
"description": "Collection title",
"title": "Entry Title",
"type": "string"
},
"instruments": {
"description": "Instrument short names",
"items": {
"type": "string"
},
"title": "Instruments",
"type": "array"
},
"is_ongoing": {
"default": false,
"description": "Whether the collection is ongoing",
"title": "Is Ongoing",
"type": "boolean"
},
"native_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The native ID of the collection record",
"title": "Native Id"
},
"platforms": {
"description": "Platform short names",
"items": {
"type": "string"
},
"title": "Platforms",
"type": "array"
},
"processing_level_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Processing level (e.g., L3, L4)",
"title": "Processing Level Id"
},
"provider_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The provider ID of the collection",
"title": "Provider Id"
},
"related_urls": {
"description": "List of related URLs (e.g., documentation, guides)",
"items": {
"additionalProperties": true,
"type": "object"
},
"title": "Related Urls",
"type": "array"
},
"revision_id": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"description": "The revision ID of the collection metadata",
"title": "Revision Id"
},
"science_keywords": {
"description": "GCMD science keyword hierarchy (Category/Topic/Term/VariableLevel)",
"items": {
"additionalProperties": true,
"type": "object"
},
"title": "Science Keywords",
"type": "array"
},
"short_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Collection short name",
"title": "Short Name"
},
"spatial_resolution": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Human-readable spatial resolution",
"title": "Spatial Resolution"
},
"temporal_resolution": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Human-readable temporal resolution",
"title": "Temporal Resolution"
},
"time_end": {
"anyOf": [
{
"format": "date-time",
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "End of temporal coverage",
"title": "Time End"
},
"time_start": {
"anyOf": [
{
"format": "date-time",
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Start of temporal coverage",
"title": "Time Start"
},
"version": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Collection version",
"title": "Version"
}
},
"required": [
"concept_id",
"entry_title"
],
"title": "CollectionResult",
"type": "object"
},
"title": "Collections",
"type": "array"
},
"error_message": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Error details when status is error",
"title": "Error Message"
},
"next_cursor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Pagination token for the next page of results",
"title": "Next Cursor"
},
"status": {
"description": "Status of the tool execution",
"enum": [
"success",
"no_results",
"error"
],
"title": "SearchStatus",
"type": "string"
},
"total_hits": {
"default": 0,
"description": "Total number of matching items",
"title": "Total Hits",
"type": "integer"
}
},
"required": [
"status"
],
"title": "GetCollectionsOutput",
"type": "object"
}
},
{
"description": "Search NASA CMR granules for a specific parent collection and return up to 10 lightweight normalized results.\n\nKey return fields in each item:\n- concept_id: CMR granule concept ID\n- native_id: native ID of the granule record\n- revision_id: revision ID of the granule metadata\n- provider_id: provider ID of the granule\n- granule_ur: primary granule identifier\n- time_start / time_end: temporal coverage bounds\n- access_urls: actionable data access URLs\n- cloud_cover: cloud cover percentage\n- day_night_flag: DAY, NIGHT, BOTH, or UNSPECIFIED\n- size_mb: file size in megabytes\n- data_format: file format (e.g., NetCDF-4, GeoTIFF)\n- bounding_box: [West, South, East, North] Minimum Bounding Rectangle (MBR) footprint. Note: for swath data or irregular polygons, this bounding box fully encloses the data but may contain empty space at the corners.\n\nIMPORTANT — data availability checks: Without temporal and/or spatial filters, results represent ALL granules ever archived in the collection, which may span decades and the entire globe. total_hits without filters tells you the full archive size, NOT whether data exists for a specific area or time period. To verify availability for a specific region and/or period, apply the corresponding spatial or temporal filters. Single-filter queries (e.g., temporal-only) are completely valid and should be used when the user only specifies one constraint, but combining both provides the most precise availability answer.\n\nKey parameters:\n- collection_concept_id: required parent collection concept ID\n- temporal_start_date / temporal_end_date: filter to granules overlapping this time window — always set when the user specifies a time period\n- spatial_wkt_geometry: filter to granules intersecting this area — always set when the user specifies a geographic region\n- cloud_cover_min / cloud_cover_max: filter optical imagery by cloud cover percentage (0–100). Only set for optical/visible imagery collections (Landsat, MODIS, VIIRS, Sentinel-2 via CMR). Do NOT set for non-optical data (SAR, altimetry, model output, etc.)\n\nIteration & Refinement:\n- Results are strictly capped at 10 items to optimize context window usage.\n- If total_hits exceeds 10 and you lack the necessary results, do not attempt to page. Refine your query by adding tighter spatial or temporal constraints.\n\nTips:\n- For the most precise availability check, provide both temporal and spatial filters if the user specifies both; otherwise, apply whichever constraint they provided\n- total_hits in the response reflects the filtered count — zero means no data for that combination\n- When users ask for \"clear\" or \"cloud-free\" imagery, set cloud_cover_max to a low value (e.g., 10 or 20)",
"inputSchema": {
"additionalProperties": false,
"properties": {
"cloud_cover_max": {
"anyOf": [
{
"maximum": 100,
"minimum": 0,
"type": "number"
},
{
"type": "null"
}
],
"default": null,
"description": "Maximum cloud cover percentage (0–100, inclusive). Use with cloud_cover_min to filter optical/visible imagery granules by cloud cover. For example, set cloud_cover_max=20 to find mostly clear scenes. Only applicable to collections that report cloud cover (e.g., Landsat, MODIS, etc). Omit for non-optical data (SAR, altimetry, etc.)."
},
"cloud_cover_min": {
"anyOf": [
{
"maximum": 100,
"minimum": 0,
"type": "number"
},
{
"type": "null"
}
],
"default": null,
"description": "Minimum cloud cover percentage (0–100, inclusive). Use with cloud_cover_max to filter optical/visible imagery granules by cloud cover. Only applicable to collections that report cloud cover (e.g., Landsat, MODIS, etc). Omit for non-optical data (SAR, altimetry, etc.)."
},
"collection_concept_id": {
"description": "Parent collection concept ID (format: C<number>-<PROVIDER>, e.g., C2723758340-GES_DISC). Required to scope granule search.",
"type": "string"
},
"cursor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Pagination token for the next page of results. Pass the exact next_cursor string returned by the previous tool call. Cursors are query-scoped: they lock in the original search parameters and cannot be reused across different tools or different queries. If you need to change any search parameter, start a new search without a cursor."
},
"day_night_flag": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Filter granules by day/night acquisition flag. Values: 'DAY', 'NIGHT', 'UNSPECIFIED'."
},
"fields": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null
},
"limit": {
"default": 10,
"description": "Maximum number of results to return (default 10, max 50). Keep this small to avoid context window bloat. When using limit > 10, always specify the fields parameter.",
"type": "integer"
},
"sort_key": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Sort key for granule results. e.g., '-start_date' (newest first), 'start_date' (oldest first). CMR default is relevance score. For ongoing or near-real-time (NRT) missions where the user wants the most recent data, always use '-start_date' — CMR's default relevance scoring may return historical data first if sort_key is not explicitly set."
},
"spatial_wkt_geometry": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Spatial filter as WKT geometry. Supported types: POLYGON((lon lat, ...)), POINT(lon lat), or LINESTRING(lon lat, ...).Finds granules with spatial extent intersecting this area. CMR returns any granule that touches this shape, so precise geometries are preferred to prevent false positives. Set this whenever the user specifies a geographic region — omitting it returns granules from the entire globe regardless of location."
},
"temporal_end_date": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "End of temporal filter in ISO 8601 format (e.g., 2024-01-31T23:59:59Z). Finds granules whose temporal extent overlaps this window. Set this whenever the user specifies a time period — omitting it returns granules from the entire collection archive regardless of date."
},
"temporal_start_date": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Start of temporal filter in ISO 8601 format (e.g., 2024-01-01T00:00:00Z). Finds granules whose temporal extent overlaps this window. Set this whenever the user specifies a time period — omitting it returns granules from the entire collection archive regardless of date."
}
},
"required": [
"collection_concept_id"
],
"type": "object"
},
"name": "get_granules",
"outputSchema": {
"description": "Output model for get_granules.",
"properties": {
"error_message": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Error details when status is error",
"title": "Error Message"
},
"granules": {
"description": "Normalized granule results mapped from UMM-G",
"items": {
"description": "Minimal granule result for direct CMR-backed retrieval.",
"properties": {
"access_urls": {
"description": "Actionable data access URLs (Note: Access requires Earthdata Login authentication)",
"items": {
"type": "string"
},
"title": "Access Urls",
"type": "array"
},
"additional_attributes": {
"description": "Provider-specific attributes (e.g., tile coords, quality flags) — array of {name, values[]}",
"items": {
"additionalProperties": true,
"type": "object"
},
"title": "Additional Attributes",
"type": "array"
},
"bounding_box": {
"anyOf": [
{
"items": {
"type": "number"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"description": "[West, South, East, North] Minimum Bounding Rectangle (MBR). Note: For swath data or irregular polygons, this bounding box fully encloses the data but may contain empty space at the corners.",
"title": "Bounding Box"
},
"cloud_cover": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"default": null,
"description": "Cloud cover percentage",
"title": "Cloud Cover"
},
"collection_concept_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Parent collection concept ID",
"title": "Collection Concept Id"
},
"concept_id": {
"description": "CMR granule concept ID",
"title": "Concept Id",
"type": "string"
},
"data_format": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "File format (e.g., NetCDF-4, GeoTIFF)",
"title": "Data Format"
},
"day_night_flag": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "DAY, NIGHT, BOTH, or UNSPECIFIED",
"title": "Day Night Flag"
},
"granule_ur": {
"description": "Granule UR",
"title": "Granule Ur",
"type": "string"
},
"native_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The native ID of the granule record",
"title": "Native Id"
},
"orbit_info": {
"description": "Orbit calculated spatial domains — array of {orbit_number, equator_crossing_longitude, equator_crossing_date_time}",
"items": {
"additionalProperties": true,
"type": "object"
},
"title": "Orbit Info",
"type": "array"
},
"producer_granule_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Producer granule ID",
"title": "Producer Granule Id"
},
"production_date": {
"anyOf": [
{
"format": "date-time",
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Date the granule was generated (ProductionDateTime)",
"title": "Production Date"
},
"provider_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The provider ID of the granule",
"title": "Provider Id"
},
"revision_id": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"description": "The revision ID of the granule metadata",
"title": "Revision Id"
},
"size_mb": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"default": null,
"description": "Size of the data granule in MB",
"title": "Size Mb"
},
"time_end": {
"anyOf": [
{
"format": "date-time",
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Granule temporal end",
"title": "Time End"
},
"time_start": {
"anyOf": [
{
"format": "date-time",
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Granule temporal start",
"title": "Time Start"
}
},
"required": [
"concept_id",
"granule_ur"
],
"title": "GranuleResult",
"type": "object"
},
"title": "Granules",
"type": "array"
},
"next_cursor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Pagination token for the next page of results",
"title": "Next Cursor"
},
"status": {
"description": "Status of the tool execution",
"enum": [
"success",
"no_results",
"error"
],
"title": "SearchStatus",
"type": "string"
},
"total_hits": {
"default": 0,
"description": "Total number of matching items",
"title": "Total Hits",
"type": "integer"
}
},
"required": [
"status"
],
"title": "GetGranulesOutput",
"type": "object"
}
},
{
"description": "Discover official Earthdata vocabulary (like 'ATMOSPHERIC WATER VAPOR') directly from NASA's Keyword Management System (KMS). Use this to find the exact preferred labels to construct successful get_collections searches.\n\nKey fields in each returned item:\n- prefLabel: The preferred label to use in searches\n- uuid: The KMS concept UUID\n- definition: Context and expanded acronyms\n- scheme: The vocabulary scheme (e.g. sciencekeywords, platforms)",
"inputSchema": {
"additionalProperties": false,
"properties": {
"cursor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Pagination token for the next page of results. Pass the exact next_cursor string returned by the previous tool call. Cursors are query-scoped: they lock in the original search parameters and cannot be reused across different tools or different queries. If you need to change any search parameter, start a new search without a cursor."
},
"fields": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null
},
"limit": {
"default": 10,
"description": "Maximum number of results to return (default 10, max 50). Keep this small to avoid context window bloat. When using limit > 10, always specify the fields parameter.",
"type": "integer"
},
"query": {
"type": "string"
},
"scheme": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null
}
},
"required": [
"query"
],
"type": "object"
},
"name": "get_keywords",
"outputSchema": {
"description": "Output model for get_keywords.",
"properties": {
"error_message": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Error details when status is error",
"title": "Error Message"
},
"keywords": {
"description": "List of matched KMS terms",
"items": {
"description": "A single matching KMS keyword result.",
"properties": {
"definition": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The primary definition of the concept, if available",
"title": "Definition"
},
"prefLabel": {
"description": "The preferred label of the KMS concept",
"title": "Preflabel",
"type": "string"
},
"scheme": {
"additionalProperties": {
"type": "string"
},
"description": "The scheme the concept belongs to",
"title": "Scheme",
"type": "object"
},
"uuid": {
"description": "The unique UUID of the KMS concept",
"title": "Uuid",
"type": "string"
}
},
"required": [
"uuid",
"prefLabel",
"scheme"
],
"title": "KeywordResult",
"type": "object"
},
"title": "Keywords",
"type": "array"
},
"next_cursor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Pagination token for the next page; None when no more results",
"title": "Next Cursor"
},
"status": {
"description": "Status of the tool execution",
"enum": [
"success",
"no_results",
"error"
],
"title": "SearchStatus",
"type": "string"
},
"total_hits": {
"default": 0,
"description": "Total number of matching items",
"title": "Total Hits",
"type": "integer"
}
},
"required": [
"status"
],
"title": "GetKeywordsOutput",
"type": "object"
}
},
{
"description": "Search NASA CMR services for a specific parent collection and return all associated normalized UMM-S records.\n\nKey fields in each returned item:\n- concept_id: CMR service concept ID\n- native_id: native ID of the service record\n- revision_id: revision ID of the service metadata\n- provider_id: provider ID of the service\n- name: service name\n- type: service type (e.g., OPeNDAP, WCS, Harmony, WMS, WMTS, ESI, EGI - No Processing)\n- version: service version string\n- description: human-readable service description\n- url: Primary endpoint URL information\n- service_options: supported output formats, projections, subset types, and interpolation methods\n- operation_metadata: operation names (e.g., GetCapabilities, GetMap) and distributed computing platform\n\nKey parameters:\n- collection_concept_id: required parent collection concept ID\n\nIteration & Refinement:\n- All services associated with the collection are fetched in a single request. Paging is not supported.\n\nNote: A collection may be associated with multiple services of different types. Check type to distinguish between data access services (e.g., OPeNDAP, WCS) and discovery/visualization services (e.g., WMS, WMTS).",
"inputSchema": {
"additionalProperties": false,
"properties": {
"collection_concept_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null
},
"cursor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Pagination token for the next page of results. Pass the exact next_cursor string returned by the previous tool call. Cursors are query-scoped: they lock in the original search parameters and cannot be reused across different tools or different queries. If you need to change any search parameter, start a new search without a cursor."
},
"fields": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null
},
"keyword": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null
},
"limit": {
"default": 10,
"description": "Maximum number of results to return (default 10, max 50). Keep this small to avoid context window bloat. When using limit > 10, always specify the fields parameter.",
"type": "integer"
},
"type": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null
}
},
"type": "object"
},
"name": "get_services",
"outputSchema": {
"description": "Output model for get_services.",
"properties": {
"error_message": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Error details when status is error",
"title": "Error Message"
},
"next_cursor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Pagination token for the next page",
"title": "Next Cursor"
},
"services": {
"description": "Normalized service results mapped from UMM-S",
"items": {
"description": "Minimal service result for direct CMR-backed retrieval.",
"properties": {
"access_constraints": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Authentication or authorization requirements",
"title": "Access Constraints"
},
"concept_id": {
"description": "CMR service concept ID",
"title": "Concept Id",
"type": "string"
},
"description": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "A brief description of the service",
"title": "Description"
},
"long_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The long name of the service",
"title": "Long Name"
},
"name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The name of the service",
"title": "Name"
},
"native_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The native ID of the service record",
"title": "Native Id"
},
"operation_metadata": {
"anyOf": [
{
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"description": "Operation names and distributed computing platform",
"title": "Operation Metadata"
},
"provider_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The provider ID of the service",
"title": "Provider Id"
},
"related_urls": {
"anyOf": [
{
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"description": "Documentation, guides, or other related links",
"title": "Related Urls"
},
"revision_id": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"description": "The revision ID of the service metadata",
"title": "Revision Id"
},
"service_keywords": {
"anyOf": [
{
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"description": "Controlled vocabulary for service capability",
"title": "Service Keywords"
},
"service_options": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null,
"description": "Subset types, supported projections, output formats",
"title": "Service Options"
},
"service_organizations": {
"anyOf": [
{
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"description": "Organizations that run the service endpoint",
"title": "Service Organizations"
},
"type": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The type of the service",
"title": "Type"
},
"url": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null,
"description": "Primary endpoint URL information",
"title": "Url"
},
"use_constraints": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Legal restrictions or usage limits",
"title": "Use Constraints"
},
"version": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The edition or version of the service",
"title": "Version"
}
},
"required": [
"concept_id"
],
"title": "ServiceResult",
"type": "object"
},
"title": "Services",
"type": "array"
},
"status": {
"description": "Status of the tool execution",
"enum": [
"success",
"no_results",
"error"
],
"title": "SearchStatus",
"type": "string"
},
"total_hits": {
"default": 0,
"description": "Total number of matching items",
"title": "Total Hits",
"type": "integer"
}
},
"required": [
"status"
],
"title": "GetServicesOutput",
"type": "object"
}
},
{
"description": "Search NASA CMR tools for a specific parent collection and return all associated normalized UMM-T records.\n\nKey fields in each returned item:\n- concept_id: CMR tool concept ID\n- native_id: native ID of the tool record\n- revision_id: revision ID of the tool metadata\n- provider_id: provider ID of the tool\n- name: tool name\n- type: tool type (e.g., Downloadable Tool, Web User Interface, Web Portal, Model)\n- version: tool version string\n- description: human-readable tool description\n- url: Primary URL for directly accessing the tool\n- supported_input_formats: file formats the tool can read (e.g., HDF5, NETCDF-4, GeoTIFF)\n- supported_output_formats: file formats the tool can produce\n- supported_operating_systems: OS compatibility (name and version)\n- supported_browsers: browser compatibility (name and version)\n- supported_software_languages: programming language compatibility\n- tool_keywords: Earth science keyword taxonomy for the tool\n- organizations: providers, developers, or publishers of the tool\n- potential_action: smart handoff definition for parameterized deep links (e.g., 'Open in Giovanni')\n\nKey parameters:\n- collection_concept_id: required parent collection concept ID\n\nIteration & Refinement:\n- All tools associated with the collection are fetched in a single request. Paging is not supported.\n\nNote: A collection may be associated with multiple tools of different types. Check type to distinguish between downloadable tools, web user interfaces, and web portals.",
"inputSchema": {
"additionalProperties": false,
"properties": {
"collection_concept_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null
},
"cursor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Pagination token for the next page of results. Pass the exact next_cursor string returned by the previous tool call. Cursors are query-scoped: they lock in the original search parameters and cannot be reused across different tools or different queries. If you need to change any search parameter, start a new search without a cursor."
},
"fields": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null
},
"keyword": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null
},
"limit": {
"default": 10,
"description": "Maximum number of results to return (default 10, max 50). Keep this small to avoid context window bloat. When using limit > 10, always specify the fields parameter.",
"type": "integer"
}
},
"type": "object"
},
"name": "get_tools",
"outputSchema": {
"description": "Output model for get_tools.",
"properties": {
"error_message": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Error details when status is error",
"title": "Error Message"
},
"next_cursor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Pagination token for the next page; None when no more results",
"title": "Next Cursor"
},
"status": {
"description": "Status of the tool execution",
"enum": [
"success",
"no_results",
"error"
],
"title": "SearchStatus",
"type": "string"
},
"tools": {
"description": "Normalized tool results mapped from UMM-T",
"items": {
"description": "Normalized tool result for direct CMR-backed retrieval.",
"properties": {
"access_constraints": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Constraints for accessing the tool",
"title": "Access Constraints"
},
"concept_id": {
"description": "CMR tool concept ID",
"title": "Concept Id",
"type": "string"
},
"description": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "A brief description of the tool",
"title": "Description"
},
"doi": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Digital Object Identifier of the tool",
"title": "Doi"
},
"long_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The long name of the tool",
"title": "Long Name"
},
"name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The name of the tool",
"title": "Name"
},
"native_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The native ID of the tool record",
"title": "Native Id"
},
"organizations": {
"anyOf": [
{
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"description": "Organizations responsible for the tool",
"title": "Organizations"
},
"potential_action": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null,
"description": "Smart handoff definition for parameterized deep links",
"title": "Potential Action"
},
"provider_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The provider ID of the tool",
"title": "Provider Id"
},
"quality": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null,
"description": "Quality information about the tool",
"title": "Quality"
},
"related_urls": {
"anyOf": [
{
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"description": "Documentation, guides, or other related links",
"title": "Related Urls"
},
"revision_id": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"description": "The revision ID of the tool metadata",
"title": "Revision Id"
},
"supported_browsers": {
"anyOf": [
{
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"description": "Browsers and versions supported by the tool",
"title": "Supported Browsers"
},
"supported_input_formats": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"description": "List of input format names supported by the tool",
"title": "Supported Input Formats"
},
"supported_operating_systems": {
"anyOf": [
{
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"description": "Operating systems and versions supported by the tool",
"title": "Supported Operating Systems"
},
"supported_output_formats": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"description": "List of output format names supported by the tool",
"title": "Supported Output Formats"
},
"supported_software_languages": {
"anyOf": [
{
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"description": "Programming languages and versions supported by the tool",
"title": "Supported Software Languages"
},
"tool_keywords": {
"anyOf": [
{
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"description": "Earth science keywords representative of the tool",
"title": "Tool Keywords"
},
"type": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The type of the tool (e.g., Downloadable Tool, Web User Interface, Web Portal, Model)",
"title": "Type"
},
"url": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null,
"description": "Primary URL for accessing the tool",
"title": "Url"
},
"use_constraints": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null,
"description": "Restrictions or limitations on using the tool",
"title": "Use Constraints"
},
"version": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The edition or version of the tool",
"title": "Version"
}
},
"required": [
"concept_id"
],
"title": "ToolResult",
"type": "object"
},
"title": "Tools",
"type": "array"
},
"total_hits": {
"default": 0,
"description": "Total number of matching items",
"title": "Total Hits",
"type": "integer"
}
},
"required": [
"status"
],
"title": "GetToolsOutput",
"type": "object"
}
},
{
"description": "Discover scientific variables and measurements associated with a collection, or look up variables by keyword. Use this tool to understand dataset variables, dimensions, and data processing parameters (such as scale, offset, and fill values) before downloading or analyzing data.\n\nKey fields in each returned item:\n- concept_id: CMR variable concept ID\n- name: Variable short name\n- long_name: Variable long name\n- definition: Variable definition\n- data_type: Data type of the variable\n- units: Units of measurement\n- scale: Scale factor\n- offset: Offset value\n- fill_values: Values indicating missing or invalid data\n- valid_ranges: Valid data ranges\n- dimensions: Variable dimensions",
"inputSchema": {
"additionalProperties": false,
"properties": {
"collection_concept_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null
},
"cursor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Pagination token for the next page of results. Pass the exact next_cursor string returned by the previous tool call. Cursors are query-scoped: they lock in the original search parameters and cannot be reused across different tools or different queries. If you need to change any search parameter, start a new search without a cursor."
},
"fields": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null
},
"keyword": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null
},
"limit": {
"default": 10,
"description": "Maximum number of results to return (default 10, max 50). Keep this small to avoid context window bloat. When using limit > 10, always specify the fields parameter.",
"type": "integer"
}
},
"type": "object"
},
"name": "get_variables",
"outputSchema": {
"description": "Output model for get_variables.",
"properties": {
"error_message": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Error details when status is error",
"title": "Error Message"
},
"next_cursor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Pagination token for the next page; None when no more results",
"title": "Next Cursor"
},
"status": {
"description": "Status of the tool execution",
"enum": [
"success",
"no_results",
"error"
],
"title": "SearchStatus",
"type": "string"
},
"total_hits": {
"default": 0,
"description": "Total number of matching items",
"title": "Total Hits",
"type": "integer"
},
"variables": {
"description": "Normalized variable results mapped from UMM-V",
"items": {
"description": "Normalized variable result for direct CMR-backed retrieval.",
"properties": {
"concept_id": {
"description": "CMR variable concept ID",
"title": "Concept Id",
"type": "string"
},
"data_type": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The data type of the variable",
"title": "Data Type"
},
"definition": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The definition of the variable",
"title": "Definition"
},
"dimensions": {
"anyOf": [
{
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"description": "Dimensions associated with the variable",
"title": "Dimensions"
},
"fill_values": {
"anyOf": [
{
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"description": "Fill values used for missing or invalid data",
"title": "Fill Values"
},
"long_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The long name of the variable",
"title": "Long Name"
},
"measurement_identifiers": {
"anyOf": [
{
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"description": "Measurement context and provenance",
"title": "Measurement Identifiers"
},
"name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The short name of the variable",
"title": "Name"
},
"offset": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"default": null,
"description": "The offset for the variable data",
"title": "Offset"
},
"related_urls": {
"anyOf": [
{
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"description": "URLs specific to the variable",
"title": "Related Urls"
},
"sampling_identifiers": {
"anyOf": [
{
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"description": "Sampling method context",
"title": "Sampling Identifiers"
},
"scale": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"default": null,
"description": "The scale factor for the variable data",
"title": "Scale"
},
"science_keywords": {
"anyOf": [
{
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"description": "GCMD Science Keywords hierarchy",
"title": "Science Keywords"
},
"sets": {
"anyOf": [
{
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"description": "Logical groupings for the variable",
"title": "Sets"
},
"standard_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The CF Standard Name of the variable",
"title": "Standard Name"
},
"units": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The units of the variable",
"title": "Units"
},
"valid_ranges": {
"anyOf": [
{
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"description": "Valid data ranges for the variable",
"title": "Valid Ranges"
},
"variable_sub_type": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Sub-type of variable",
"title": "Variable Sub Type"
},
"variable_type": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Type of variable (e.g., SCIENCE_VARIABLE, COORDINATE)",
"title": "Variable Type"
}
},
"required": [
"concept_id"
],
"title": "VariableResult",
"type": "object"
},
"title": "Variables",
"type": "array"
}
},
"required": [
"status"
],
"title": "GetVariablesOutput",
"type": "object"
}
}
]
}Verify it yourself
curl -s https://api.teppi.xyz/v1/evidence/sha256:f73b333a49d6f5b190e3e9f5a6831ed232276ca3e558912d7c21e0636b3c0841 | sha256sum