diff --git a/README.md b/README.md index 5b392f0..7150fdc 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,7 @@ claude mcp add mcgibs-local -- uv run --directory /path/to/mcgibs mcgibs ## Conversational Examples -These examples show what interacting with mcgibs looks like from any MCP client. Tool calls and responses are abbreviated for readability. +These examples show what interacting with mcgibs looks like from any MCP client. Tool calls and responses are abbreviated for readability. All images below were fetched live from NASA GIBS using the mcgibs MCP tools. ### "What's happening in the Amazon right now?" @@ -96,22 +96,24 @@ The assistant resolves the location, fetches true color imagery, and searches fo {"display_name": "Amazon Rainforest", "lat": -3.46, "lon": -62.21, "bbox": {"west": -73.98, "south": -16.52, "east": -43.75, "north": 5.27}} -→ get_imagery("MODIS_Terra_CorrectedReflectance_TrueColor", "2025-06-01", +→ get_imagery("MODIS_Terra_CorrectedReflectance_TrueColor", "2025-08-01", place="Amazon Rainforest") - [image: true color view of the Amazon basin] +``` +MODIS true color satellite view of the Amazon Basin showing river systems threading through dense forest canopy + +*MODIS Terra Corrected Reflectance — Amazon Basin, 2025-08-01* + +``` → search_gibs_layers("vegetation") Found 12 layer(s) matching 'vegetation': MODIS_Terra_NDVI_8Day MODIS/Terra Vegetation Index (NDVI), 8-Day — from 2000-02-18 (8-Day) [has colormap] - MODIS_Terra_EVI_8Day - MODIS/Terra Enhanced Vegetation Index (EVI), 8-Day — from 2000-02-18 (8-Day) - [has colormap] ... ``` -> **Assistant:** Here's the Amazon from MODIS Terra today — you can see the river system threading through dense canopy, with some cloud cover over the western basin. I also found vegetation index layers. Want me to overlay NDVI to show vegetation density, or check for fire/deforestation activity? +> **Assistant:** Here's the Amazon from MODIS Terra — the river system is clearly visible, threading through dense canopy with sediment-laden water distinguishable from the dark forest. Some cloud cover is visible in the upper right. I also found vegetation index layers. Want me to overlay NDVI to show vegetation density, or check for fire/deforestation activity? --- @@ -121,7 +123,7 @@ The assistant resolves the location, fetches true color imagery, and searches fo > **You:** What does the AIRS surface temperature layer actually show? -The assistant fetches metadata and the colormap interpretation: +The assistant fetches metadata, the colormap interpretation, and sample imagery: ``` → get_layer_info("AIRS_L3_Surface_Air_Temperature_Daily_Day") @@ -133,20 +135,30 @@ The assistant fetches metadata and the colormap interpretation: → explain_layer_colormap("AIRS_L3_Surface_Air_Temperature_Daily_Day") Surface Air Temperature (K): - - dark blue = ~213 K (-60 C) -- extreme cold - - cyan = ~243 K (-30 C) -- severe cold - - green = ~268 K (-5 C) -- near freezing - - yellow = ~293 K (20 C) -- mild - - dark red = ~323 K (50 C) -- extreme heat - Color gradient runs from dark blues (low values) through greens to dark reds (high values). - (254 color stops total, 5 key values shown) + - light blue = below 200 K (-73.1 C) -- extreme cold + - purple = ~230 K (-43.4 C) -- extreme cold + - blue = ~260 K (-13.4 C) -- cold + - orange = ~290 K (17.1 C) -- mild + - magenta = above 320 K (46.9 C) -- extreme heat + Color gradient runs from light blues (low values) through blues to magentas (high values). + (242 color stops total, 5 key values shown) Transparent / no-data: No Data -→ get_legend("AIRS_L3_Surface_Air_Temperature_Daily_Day") - [image: horizontal color bar from blue to red, labeled 213K to 323K] +→ get_imagery("AIRS_L3_Surface_Air_Temperature_Daily_Day", "2025-07-15", + bbox=[-180, -90, 180, 90]) ``` -> **Assistant:** The AIRS instrument on NASA's Aqua satellite measures surface air temperature globally every day, and has been doing so since August 2002. The colormap runs from dark blue (around -60°C, polar regions) through greens (near freezing) to dark red (above 50°C, desert extremes). The 254 color stops give smooth gradation — areas with no valid retrieval show as transparent. +Global surface air temperature map showing warm oranges and reds at the equator, cool blues and purples at the poles + +*AIRS Surface Air Temperature — global view, 2025-07-15. Black diagonal gaps are orbital swaths where the satellite hadn't passed yet.* + +``` +→ get_legend("AIRS_L3_Surface_Air_Temperature_Daily_Day") +``` + +Color legend bar for surface air temperature, ranging from below 200K to above 320K + +> **Assistant:** The AIRS instrument on NASA's Aqua satellite measures surface air temperature globally every day, and has been doing so since August 2002. The colormap runs from light blue (below -73°C, Antarctic interior) through purples and blues (cold/freezing) to orange (mild, ~17°C) and magenta (above 47°C, Saharan extremes). The diagonal black stripes are orbital gaps — the satellite covers the full globe but not all locations on the same day pass. Areas with no valid retrieval show as transparent. --- @@ -160,28 +172,22 @@ The assistant uses the `climate_monitor` workflow — search, verify dates, comp ``` → search_gibs_layers("sea ice concentration") - Found 6 layer(s) matching 'sea ice concentration': - AMSR2_Sea_Ice_Concentration_12km - AMSR2 Sea Ice Concentration, 12 km — from 2012-07-02 (Daily) + Found 8 layer(s) matching 'sea ice concentration': + AMSRU2_Sea_Ice_Concentration_12km + Sea Ice Concentration (12 km, AMSRU2, GCOM-W1) — from 2012-07-02 (Daily) [has colormap] ... -→ explain_layer_colormap("AMSR2_Sea_Ice_Concentration_12km") - Sea Ice Concentration (%): - - dark blue = ~15% - - cyan = ~40% - - light grey = ~70% - - white = ~100% - Color gradient runs from dark blues (low values) through cyans to whites (high values). - Transparent / no-data: No Data, Land - -→ compare_dates("AMSR2_Sea_Ice_Concentration_12km", +→ compare_dates("AMSRU2_Sea_Ice_Concentration_12km", "2025-03-01", "2025-09-01", bbox=[-180, 60, 180, 90]) - [image: side-by-side comparison — March (left) vs September (right)] ``` -> **Assistant:** The side-by-side view is striking. In March, the Arctic Ocean is almost entirely white (90-100% ice concentration), with the ice edge extending well into the Bering Sea and Barents Sea. By September, the ice has retreated dramatically — the white core is confined to a smaller region around the pole, with large stretches of dark blue (15-40%) and open water visible along the Northeast Passage and in Hudson Bay. The colormap tells us white = solid pack ice and dark blue = scattered ice at 15% concentration. +Side-by-side comparison of Arctic sea ice: March 2025 showing near-complete coverage versus September 2025 showing dramatic retreat + +*AMSRU2 Sea Ice Concentration — Left: March 2025 (winter maximum) | Right: September 2025 (summer minimum). White/pink = high concentration, colorful edges = ice margin with varying concentration, black = open water or land.* + +> **Assistant:** The side-by-side view is striking. In March (left), the Arctic Ocean shows near-complete ice coverage — white and pale pink across the entire basin, with the ice edge extending well into the Bering Sea and Barents Sea. By September (right), the ice has retreated dramatically — the remaining pack ice is confined to a much smaller core around the pole, with extensive open water (black) visible along the entire Russian coastline and into the Canadian Archipelago. The colorful fringe along the ice edge shows the marginal ice zone where concentration drops from solid pack to scattered floes. --- @@ -212,7 +218,7 @@ The assistant searches for complementary layers, checks dates, and builds a comp ["MODIS_Terra_CorrectedReflectance_TrueColor", "MODIS_Terra_Aerosol_Optical_Depth"], "2025-01-08", place="Los Angeles") - [image: true color with aerosol optical depth overlay] + [composite image: true color with aerosol optical depth overlay] → explain_layer_colormap("MODIS_Terra_Aerosol_Optical_Depth") Aerosol Optical Depth: diff --git a/docs/images/amazon-true-color.jpg b/docs/images/amazon-true-color.jpg new file mode 100644 index 0000000..cc8fa22 Binary files /dev/null and b/docs/images/amazon-true-color.jpg differ diff --git a/docs/images/arctic-ice-comparison.jpg b/docs/images/arctic-ice-comparison.jpg new file mode 100644 index 0000000..f4d20bb Binary files /dev/null and b/docs/images/arctic-ice-comparison.jpg differ diff --git a/docs/images/temperature-colormap.txt b/docs/images/temperature-colormap.txt new file mode 100644 index 0000000..cad211d --- /dev/null +++ b/docs/images/temperature-colormap.txt @@ -0,0 +1,10 @@ +Surface Air Temperature (K): + - light blue = below 200 K (-73.1 C) -- extreme cold + - purple = ~230 K (-43.4 C) -- extreme cold + - blue = ~260 K (-13.4 C) -- cold + - orange = ~290 K (17.1 C) -- mild + - magenta = above 320 K (46.9 C) -- extreme heat + +Color gradient runs from light blues (low values) through blues to magentas (high values). +(242 color stops total, 5 key values shown) +Transparent / no-data: No Data \ No newline at end of file diff --git a/docs/images/temperature-global.jpg b/docs/images/temperature-global.jpg new file mode 100644 index 0000000..5eb0806 Binary files /dev/null and b/docs/images/temperature-global.jpg differ diff --git a/docs/images/temperature-legend.png b/docs/images/temperature-legend.png new file mode 100644 index 0000000..8209ca5 Binary files /dev/null and b/docs/images/temperature-legend.png differ diff --git a/pyproject.toml b/pyproject.toml index 0c7c617..6759208 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "mcgibs" -version = "2026.02.18.3" +version = "2026.02.18.4" description = "FastMCP server for NASA Global Imagery Browse Services (GIBS)" readme = "README.md" requires-python = ">=3.12" diff --git a/scripts/fetch_readme_images.py b/scripts/fetch_readme_images.py new file mode 100644 index 0000000..98b9624 --- /dev/null +++ b/scripts/fetch_readme_images.py @@ -0,0 +1,110 @@ +"""Fetch example images for the README via the mcgibs MCP server. + +Uses the FastMCP in-process Client to call tools through the MCP protocol, +exactly as any MCP client would. Images are saved to docs/images/. +""" + +import asyncio +import base64 +import sys +from pathlib import Path + +from fastmcp import Client + +# Wire up the server module so the client is initialized +import mcgibs.server as server_module +from mcgibs.client import GIBSClient +from mcgibs.server import mcp + +OUT = Path(__file__).parent.parent / "docs" / "images" + + +async def save_imagery(client: Client, filename: str, tool: str, params: dict) -> None: + """Call an imagery tool and save the returned image to disk.""" + print(f" Fetching {filename}...", file=sys.stderr) + result = await client.call_tool(tool, params) + + # Find the ImageContent in the response + for content in result.content: + if content.type == "image": + img_bytes = base64.b64decode(content.data) + path = OUT / filename + path.write_bytes(img_bytes) + size_kb = len(img_bytes) / 1024 + print(f" Saved {path} ({size_kb:.0f} KB)", file=sys.stderr) + return + + # If we got text only (error case), print it + for content in result.content: + if content.type == "text": + print(f" Warning: {content.text[:200]}", file=sys.stderr) + + +async def main(): + OUT.mkdir(parents=True, exist_ok=True) + + # Initialize GIBS client (normally done by middleware on first connection) + print("Initializing GIBS client...", file=sys.stderr) + gibs = GIBSClient() + await gibs.initialize() + server_module._client = gibs + print(f"Ready — {len(gibs.layer_index)} layers loaded", file=sys.stderr) + + try: + async with Client(mcp) as client: + # 1. Amazon true color — natural satellite view + await save_imagery(client, "amazon-true-color.jpg", "get_imagery", { + "layer_id": "MODIS_Terra_CorrectedReflectance_TrueColor", + "date": "2025-08-01", + "place": "Amazon Rainforest", + "width": 1024, + "height": 768, + "format": "jpeg", + }) + + # 2. Global surface air temperature — scientific data product + await save_imagery(client, "temperature-global.jpg", "get_imagery", { + "layer_id": "AIRS_L3_Surface_Air_Temperature_Daily_Day", + "date": "2025-07-15", + "bbox": [-180, -90, 180, 90], + "width": 1024, + "height": 512, + "format": "jpeg", + }) + + # 3. Arctic sea ice comparison — March (max) vs September (min) + await save_imagery( + client, "arctic-ice-comparison.jpg", "compare_dates", { + "layer_id": "AMSRU2_Sea_Ice_Concentration_12km", + "date_before": "2025-03-01", + "date_after": "2025-09-01", + "bbox": [-180, 60, 180, 90], + }, + ) + + # 4. Surface temperature colormap legend + await save_imagery( + client, "temperature-legend.png", "get_legend", { + "layer_id": "AIRS_L3_Surface_Air_Temperature_Daily_Day", + "orientation": "horizontal", + }, + ) + + # 5. Colormap explanation (text, not image) + print(" Fetching temperature colormap explanation...", file=sys.stderr) + result = await client.call_tool( + "explain_layer_colormap", + {"layer_id": "AIRS_L3_Surface_Air_Temperature_Daily_Day"}, + ) + explanation = result.content[0].text + (OUT / "temperature-colormap.txt").write_text(explanation) + print(f" Saved colormap explanation", file=sys.stderr) + + finally: + await gibs.close() + server_module._client = None + + print("Done!", file=sys.stderr) + + +asyncio.run(main()) diff --git a/src/mcgibs/__init__.py b/src/mcgibs/__init__.py index b126b39..5fee8af 100644 --- a/src/mcgibs/__init__.py +++ b/src/mcgibs/__init__.py @@ -1 +1 @@ -__version__ = "2026.02.18.3" +__version__ = "2026.02.18.4"